面試必備| 常見C++筆試面試題整理 - sa123
文章推薦指數: 80 %
編譯階段,g++會呼叫gcc,對於c++程式碼,兩者是等價的,但是因為gcc命令不能自動和C++程式使用的庫聯接,所以通常用g++來完成連結。
點選上方“計算機視覺life”,選擇“星標”
快速獲得最新幹貨
作者:阿貴
https://zhuanlan.zhihu.com/p/69999591
本文已授權,未經允許,不得二次轉載
gcc和g++的區別
簡單來說,gcc與g++都是GNU(組織)的一個編譯器。
需要注意以下幾點:
gcc與g++都可以編譯c程式碼與c++程式碼。
但是:字尾為.c的,gcc把它當做C程式,而g++當做是C++程式;字尾為.cpp的,兩者都會認為是C++程式。
編譯階段,g++會呼叫gcc,對於c++程式碼,兩者是等價的,但是因為gcc命令不能自動和C++程式使用的庫聯接,所以通常用g++來完成連結。
編譯可以用gcc/g++,而連結可以用g++或者gcc-lstdc++。
因為gcc命令不能自動和C++程式使用的庫聯接(當然可以選擇手動連結,使用命令如下),所以通常使用g++來完成聯接。
但在編譯階段,g++會自動呼叫gcc,二者等價。
gccmain.cpp-lstdc++
gcc編譯的四個步驟,以最簡單的hello.c為例子
一步到位:gcchello.c這條命令隱含執行了(1)預處理(2)編譯(3)彙編(4)連結這裡未指定輸出檔案,預設輸出為a.outgcc編譯C原始碼有四個步驟:預處理—->編譯—->彙編—->連結現在我們就用gcc的命令選項來逐個剖析gcc過程。
1)預處理(Pre-processing)在該階段,編譯器將C原始碼中的包含的標頭檔案如stdio.h新增進來引數:”-E”用法:gcc-Ehello.c-ohello.i作用:將hello.c預處理輸出hello.i檔案。
2)編譯(Compiling)第二步進行的是編譯階段,在這個階段中,gcc首先要檢查程式碼的規範性、是否有語法錯誤等,以確定程式碼的實際要做的工作,在檢查無誤後,gcc把程式碼翻譯成組合語言。
引數:”-S”用法:gcc–Shello.i–ohello.s作用:將預處理輸出檔案hello.i彙編成hello.s檔案。
3)彙編(Assembling)彙編階段是把編譯階段生成的”.s”檔案轉成二進位制目的碼“.o”檔案引數:“-c”用法:gcc–chello.s–ohello.o作用:將彙編輸出檔案hello.s編譯輸出hello.o檔案。
4)連結(Link)在成功編譯之後,就進入了連結階段。
用法:gcchello.o–ohello作用:將編譯輸出檔案hello.o連結成最終可執行檔案hello。
執行該可執行檔案,出現正確的結果如下。
>>>./helloHelloWorld!
C++11包含大量的新特性:包含lambda表示式,型別推導keyword:auto、decltype,和模板的大量改進。
decltype實際上有點像auto的反函式,auto能夠讓你宣告一個變數。
而decltype則能夠從一個變數或表示式中得到型別
nullptr是為了解決原來C++中NULL的二義性問題而引進的一種新的型別,由於NULL實際上代表的是0,
簡化的for迴圈,能夠用於遍歷陣列、容器、string以及由begin和end函式定義的序列(即有Iterator),for(autop:m)
lambda表示式,能夠用於建立並定義匿名的函式物件,以簡化程式設計工作。
Lambda的語法例如以下:[函式物件引數](運算子過載函式引數)->返回值型別{函式體}
vector
(1)函式中的b就是指函式能夠得到在Lambda表示式外的全域性變數,假設在[]中傳入=的話,即是能夠取得全部的外部變數,如(2)和(3)Lambda表示式
()內的引數是每次呼叫函式時傳入的引數。
->後加上的是Lambda表示式返回值的型別。
如(3)中返回了一個int型別的變數
變長引數的模板,C++11中引入了變長引數模板,所以發明了新的資料型別:tuple,tuple是一個N元組。
能夠傳入1個,2個甚至多個不同型別的資料
autot1=make_tuple(1,2.0,"C++11");autot2=make_tuple(1,2.0,"C++11",{1,0,2});
避免了從前的pair中巢狀pair的醜陋做法。
使得程式碼更加整潔
更加優雅的初始化方法,在引入C++11之前。
僅僅有陣列能使用初始化列表,其它容器想要使用初始化列表,僅僅能用下面方法:
intarr[3]={1,2,3}vector
智慧指標是一個類,這個類的建構函式中傳入一個普通指標,解構函式中釋放傳入的指標。
智慧指標的類都是棧上的物件,所以當函式(或程式)結束時會自動被釋放,
智慧指標就是一種棧上建立的物件,函式退出時會呼叫其解構函式,這個析構函數里面往往就是一堆計數之類的條件判斷,如果達到某個條件,就把真正指標指向的空間給釋放了。
注意事項:
不能將指標直接賦值給一個智慧指標,一個是類,一個是指標。
常用的智慧指標
智慧指標在C++11版本之後提供,包含在標頭檔案
不支援複製(複製建構函式)和賦值(operator=),但複製或賦值的時候不會提示出錯。
所以可能會造成程式崩潰,比如
auto_ptr
前面說過,這是好事,可防止p1和p2的解構函式試圖刪同—個物件;但如果程式隨後試圖使用p1,這將是件壞事,因為p1不再指向有效的資料。
如果再訪問p1指向的內容則會導致程式崩潰。
auto_ptr是C++98提供的解決方案,C+11已將將其摒棄,摒棄auto_ptr的原因,一句話總結就是:避免潛在的記憶體崩潰問題。
2)C++11引入的unique_ptr,也不支援複製和賦值,但比auto_ptr好,直接賦值會編譯出錯。
實在想賦值的話,需要使用:std::move。
例如:
std::unique_ptr
但unique_ptr還有更聰明的地方。
有時候,會將一個智慧指標賦給另一個並不會留下危險的懸掛指標。
當程式試圖將一個unique_ptr賦值給另一個時,如果源unique_ptr是個臨時右值,編譯器允許這麼做;如果源unique_ptr將存在一段時間,編譯器將禁止這麼做
unique_ptr
而#2不會留下懸掛的unique_ptr,因為它呼叫unique_ptr的建構函式,該建構函式建立的臨時物件在其所有權讓給pu3後就會被銷燬。
這種隨情況而已的行為表明,unique_ptr優於允許兩種賦值的auto_ptr。
3)C++11或boost的shared_ptr,基於引用計數的智慧指標。
可隨意賦值,直到記憶體的引用計數為0的時候這個記憶體會被釋放。
4)C++11或boost的weak_ptr,弱引用。
引用計數有一個問題就是互相引用形成環,這樣兩個指標指向的記憶體都無法釋放。
需要手動打破迴圈引用或使用weak_ptr。
顧名思義,weak_ptr是一個弱引用,只引用,不計數。
如果一塊記憶體被shared_ptr和weak_ptr同時引用,當所有shared_ptr析構了之後,不管還有沒有weak_ptr引用該記憶體,記憶體也會被釋放。
所以weak_ptr不保證它指向的記憶體一定是有效的,在使用之前需要檢查weak_ptr是否為空指標。
智慧指標的作用
C++程式設計中使用堆記憶體是非常頻繁的操作,堆記憶體的申請和釋放都由程式設計師自己管理。
程式設計師自己管理堆記憶體可以提高了程式的效率,但是整體來說堆記憶體的管理是麻煩的,C++11中引入了智慧指標的概念,方便管理堆記憶體。
使用普通指標,容易造成堆記憶體洩露(忘記釋放),二次釋放,野指標,程式發生異常時記憶體洩露等問題等,使用智慧指標能更好的管理堆記憶體。
1、C和C++的區別
1)C是面向過程的語言,是一個結構化的語言,考慮如何透過一個過程對輸入進行處理得到輸出;C++是面向物件的語言,主要特徵是“封裝、繼承和多型”。
封裝隱藏了實現細節,使得程式碼模組化;派生類可以繼承父類的資料和方法,擴充套件了已經存在的模組,實現了程式碼重用;多型則是“一個介面,多種實現”,透過派生類重寫父類的虛擬函式,實現了介面的重用。
2)C和C++動態管理記憶體的方法不一樣,C是使用malloc/free,而C++除此之外還有new/delete關鍵字。
3)C++支援函式過載,C不支援函式過載
4)C++中有引用,C中不存在引用的概念
2、C++中指標和引用的區別
1)指標是一個新的變數,儲存了另一個變數的地址,我們可以透過訪問這個地址來修改另一個變數;
引用只是一個別名,還是變數本身,對引用的任何操作就是對變數本身進行操作,以達到修改變數的目的
2)引用只有一級,而指標可以有多級
3)指標傳參的時候,還是值傳遞,指標本身的值不可以修改,需要透過解引用才能對指向的物件進行操作
引用傳參的時候,傳進來的就是變數本身,因此變數可以被修改
3、結構體struct和共同體union(聯合)的區別
結構體:將不同型別的資料組合成一個整體,是自定義型別
共同體:不同型別的幾個變數共同佔用一段記憶體
1)結構體中的每個成員都有自己獨立的地址,它們是同時存在的;
共同體中的所有成員佔用同一段記憶體,它們不能同時存在;
2)sizeof(struct)是記憶體對齊後所有成員長度的總和,sizeof(union)是記憶體對齊後最長資料成員的長度、
結構體為什麼要記憶體對齊呢?
1.平臺原因(移植原因):不是所有的硬體平臺都能訪問任意地址上的任意資料,某些硬體平臺只能在某些地址處取某些特定型別的資料,否則丟擲硬體異常
2.硬體原因:經過記憶體對齊之後,CPU的記憶體訪問速度大大提升。
4、#define和const的區別
1)#define定義的常量沒有型別,所給出的是一個立即數;const定義的常量有型別名字,存放在靜態區域
2)處理階段不同,#define定義的宏變數在預處理時進行替換,可能有多個複製,const所定義的變數在編譯時確定其值,只有一個複製。
3)#define定義的常量是不可以用指標去指向,const定義的常量可以用指標去指向該常量的地址
4)#define可以定義簡單的函式,const不可以定義函式
5、過載overload,覆蓋(重寫)override,隱藏(重定義)overwrite,這三者之間的區別
1)overload,將語義相近的幾個函式用同一個名字表示,但是引數列表(引數的型別,個數,順序不同)不同,這就是函式過載,返回值型別可以不同
特徵:相同範圍(同一個類中)、函式名字相同、引數不同、virtual關鍵字可有可無
2)override,派生類覆蓋基類的虛擬函式,實現介面的重用,返回值型別必須相同
特徵:不同範圍(基類和派生類)、函式名字相同、引數相同、基類中必須有virtual關鍵字(必須是虛擬函式)
3)overwrite,派生類遮蔽了其同名的基類函式,返回值型別可以不同
特徵:不同範圍(基類和派生類)、函式名字相同、引數不同或者引數相同且無virtual關鍵字
6、new、delete、malloc、free之間的關係
new/delete,malloc/free都是動態分配記憶體的方式
1)malloc對開闢的空間大小嚴格指定,而new只需要物件名
2)new為物件分配空間時,呼叫物件的建構函式,delete呼叫物件的解構函式
既然有了malloc/free,C++中為什麼還需要new/delete呢?
運算子是語言自身的特性,有固定的語義,編譯器知道意味著什麼,由編譯器解釋語義,生成相應的程式碼。
庫函式是依賴於庫的,一定程度上獨立於語言的。
編譯器不關心庫函式的作用,只保證編譯,呼叫函式引數和返回值符合語法,生成call函式的程式碼。
malloc/free是庫函式,new/delete是C++運算子。
對於非內部資料型別而言,光用malloc/free無法滿足動態物件都要求。
new/delete是運算子,編譯器保證呼叫構造和解構函式對物件進行初始化/析構。
但是庫函式malloc/free是庫函式,不會執行構造/析構。
7、delete和delete[]的區別
delete只會呼叫一次解構函式,而delete[]會呼叫每個成員的解構函式
用new分配的記憶體用delete釋放,用new[]分配的記憶體用delete[]釋放
多型,虛擬函式,純虛擬函式
多型:不同物件接收相同的訊息產生不同的動作。
多型包括編譯時多型和執行時多型
執行時多型是:透過繼承和虛擬函式來體現的。
編譯時多型:運算子過載上。
封裝可以隱藏實現細節,使得程式碼模組化;繼承可以擴充套件已存在的程式碼模組(類);它們的目的都是為了——程式碼重用。
多型也有程式碼重用的功能,還有解決專案中緊耦合的問題,提高程式的可擴充套件性。
C++實現多型的機制很簡單,在繼承體系下,將父類的某個函式給成虛擬函式(即加上virtual關鍵字),在派生類中對這個虛擬函式進行重寫,利用父類的指標或引用呼叫虛擬函式。
透過指向派生類的基類指標或引用,訪問派生類中同名覆蓋成員函式。
對於虛擬函式呼叫來說,每一個物件內部都有一個虛表指標,在構造子類物件時,執行建構函式中進行虛表的建立和虛表指標的初始化,該虛表指標被初始化為本類的虛表。
所以在程式中,不管你的物件型別如何轉換,但該物件內部的虛表指標是固定的,所以呢,才能實現動態的物件函式呼叫,這就是C++多型性實現的原理。
需要注意的幾點總結(基類有虛擬函式):1、每一個類都有虛表,單繼承的子類擁有一張虛表,子類物件擁有一個虛表指標;若子類是多重繼承(同時繼承多個基類),則子類維護多張虛擬函式表(針對不同基類構建不同虛表),該子類的物件也將包含多個虛表指標。
2、虛表可以繼承,如果子類沒有重寫虛擬函式,那麼子類虛表中仍然會有該函式的地址,只不過這個地址指向的是基類的虛擬函式實現。
如果基類3個虛擬函式,那麼基類的虛表中就有三項(虛擬函式地址),派生類也會有虛表,至少有三項,如果重寫了相應的虛擬函式,那麼虛表中的地址就會改變,指向自身的虛擬函式實現。
如果派生類有自己的虛擬函式,那麼虛表中就會新增該項。
3、派生類的虛表中虛擬函式地址的排列順序和基類的虛表中虛擬函式地址排列順序相同。
第一:編譯器在發現Father類中有虛擬函式時,會自動為每個含有虛擬函式的類生成一份虛擬函式表,也叫做虛表,該表是一個一維陣列,虛表裡儲存了虛擬函式的入口地址。
第二:編譯器會在每個物件的前四個位元組中儲存一個虛表指標,即(vptr),指向物件所屬類的虛表。
在程式執行時的合適時機,根據物件的型別去初始化vptr,從而讓vptr指向正確的虛表,從而在呼叫虛擬函式時,能找到正確的函式。
第三:所謂的合適時機,在派生類定義物件時,程式執行會自動呼叫建構函式,在建構函式中建立虛表並對虛表初始化。
在構造子類物件時,會先呼叫父類的建構函式,此時,編譯器只“看到了”父類,併為父類物件初始化虛表指標,令它指向父類的虛表;當呼叫子類的建構函式時,為子類物件初始化虛表指標,令它指向子類的虛表。
虛擬函式:在基類中用virtual的成員函式。
允許在派生類中對基類的虛擬函式重新定義。
基類的虛擬函式可以有函式體,基類也可以例項化。
虛擬函式要有函式體,否則編譯過不去。
虛擬函式在子類中可以不覆蓋。
建構函式不能是虛擬函式。
純虛擬函式:基類中為其派生類保留一個名字,以便派生類根據需要進行定義。
包含一個純虛擬函式的類是抽象類。
純虛擬函式後面有=0;抽象類不可以例項化。
但可以定義指標。
如果派生類如果不是先基類的純虛擬函式,則仍然是抽象類。
抽象類可以包含虛擬函式。
8、STL庫用過嗎?常見的STL容器有哪些?演算法用過幾個?
STL包括兩部分內容:容器和演算法
容器即存放資料的地方,比如array,vector,分為兩類,序列式容器和關聯式容器
序列式容器,其中的元素不一定有序,但是都可以被排序,比如vector,list,queue,stack,heap,priority-queue,slist
關聯式容器,內部結構是一個平衡二叉樹,每個元素都有一個鍵值和一個實值,比如map,set,hashtable,hash_set
演算法有排序,複製等,以及各個容器特定的演算法
迭代器是STL的精髓,迭代器提供了一種方法,使得它能夠按照順序訪問某個容器所含的各個元素,但無需暴露該容器的內部結構,它將容器和演算法分開,讓二者獨立設計。
9、const知道嗎?解釋一下其作用
const修飾類的成員變數,表示常量不可能被修改
const修飾類的成員函式,表示該函式不會修改類中的資料成員,不會呼叫其他非const的成員函式
const函式只能呼叫const函式,非const函式可以呼叫const函式
10、虛擬函式是怎麼實現的
每一個含有虛擬函式的類都至少有有一個與之對應的虛擬函式表,其中存放著該類所有虛擬函式對應的函式指標(地址),
類的示例物件不包含虛擬函式表,只有虛指標;
派生類會生成一個相容基類的虛擬函式表。
11、堆和棧的區別
1)棧stack存放函式的引數值、區域性變數,由編譯器自動分配釋放
堆heap,是由new分配的記憶體塊,由應用程式控制,需要程式設計師手動利用delete釋放,如果沒有,程式結束後,作業系統自動回收
2)因為堆的分配需要使用頻繁的new/delete,造成記憶體空間的不連續,會有大量的碎片
3)堆的生長空間向上,地址越大,棧的生長空間向下,地址越小
12、關鍵字static的作用
1)函式體內:static修飾的區域性變數作用範圍為該函式體,不同於auto變數,其記憶體只被分配一次,因此其值在下次呼叫的時候維持了上次的值
2)模組內:static修飾全域性變數或全域性函式,可以被模組內的所有函式訪問,但是不能被模組外的其他函式訪問,使用範圍限制在宣告它的模組內
3)類中:修飾成員變數,表示該變數屬於整個類所有,對類的所有物件只有一份複製
4)類中:修飾成員函式,表示該函式屬於整個類所有,不接受this指標,只能訪問類中的static成員變數
注意和const的區別!!!const強調值不能被修改,而static強調唯一的複製,對所有類的物件
13、STL中map和set的原理(關聯式容器)
map和set的底層實現主要透過紅黑樹來實現
紅黑樹是一種特殊的二叉查詢樹
1)每個節點或者是黑色,或者是紅色
2)根節點是黑色
3)每個葉子節點(NIL)是黑色。
[注意:這裡葉子節點,是指為空(NIL或NULL)的葉子節點!]
4)如果一個節點是紅色的,則它的子節點必須是黑色的
5)從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。
特性4)5)決定了沒有一條路徑會比其他路徑長出2倍,因此紅黑樹是接近平衡的二叉樹。
14、#include
方法:malloc/free要配套,對指標賦值的時候應該注意被賦值的指標是否需要釋放;使用的時候記得指標的長度,防止越界
16、定義和宣告的區別
宣告是告訴編譯器變數的型別和名字,不會為變數分配空間
定義需要分配空間,同一個變數可以被宣告多次,但是隻能被定義一次
17、C++檔案編譯與執行的四個階段
1)預處理:根據檔案中的預處理指令來修改原始檔的內容
2)編譯:編譯成彙編程式碼
3)彙編:把彙編程式碼翻譯成目標機器指令
4)連結:連結目的碼生成可執行程式
18、STL中的vector的實現,是怎麼擴容的?
vector使用的注意點及其原因,頻繁對vector呼叫push_back()對效能的影響和原因。
vector就是一個動態增長的陣列,裡面有一個指標指向一片連續的空間,當空間裝不下的時候,會申請一片更大的空間,將原來的資料複製過去,並釋放原來的舊空間。
當刪除的時候空間並不會被釋放,只是清空了裡面的資料。
對比array是靜態空間一旦配置了就不能改變大小。
vector的動態增加大小的時候,並不是在原有的空間上持續新的空間(無法保證原空間的後面還有可供配置的空間),而是以原大小的兩倍另外配置一塊較大的空間,然後將原內容複製過來,並釋放原空間。
在VS下是1.5倍擴容,在GCC下是2倍擴容。
在原來空間不夠儲存新值時,每次呼叫push_back方法都會重新分配新的空間以滿足新資料的新增操作。
如果在程式中頻繁進行這種操作,還是比較消耗效能的。
19、STL中unordered_map和map的區別
map是STL中的一個關聯容器,提供鍵值對的資料管理。
底層透過紅黑樹來實現,實際上是二叉排序樹和非嚴格意義上的二叉平衡樹。
所以在map內部所有的資料都是有序的,且map的查詢、插入、刪除操作的時間複雜度都是O(logN)。
unordered_map和map類似,都是儲存key-value對,可以透過key快速索引到value,不同的是unordered_map不會根據key進行排序。
unordered_map底層是一個防冗餘的雜湊表,儲存時根據key的hash值判斷元素是否相同,即unoredered_map內部是無序的。
20、C++的記憶體管理
在C++中,記憶體被分成五個區:棧、堆、自由儲存區、靜態儲存區、常量區
棧:存放函式的引數和區域性變數,編譯器自動分配和釋放
堆:new關鍵字動態分配的記憶體,由程式設計師手動進行釋放,否則程式結束後,由作業系統自動進行回收
自由儲存區:由malloc分配的記憶體,和堆十分相似,由對應的free進行釋放
全域性/靜態儲存區:存放全域性變數和靜態變數
常量區:存放常量,不允許被修改
21、建構函式為什麼一般不定義為虛擬函式?而解構函式一般寫成虛擬函式的原因?
1、建構函式不能宣告為虛擬函式
1)因為建立一個物件時需要確定物件的型別,而虛擬函式是在執行時確定其型別的。
而在構造一個物件時,由於物件還未建立成功,編譯器無法知道物件的實際型別,是類本身還是類的派生類等等
2)虛擬函式的呼叫需要虛擬函式表指標,而該指標存放在物件的記憶體空間中;若建構函式宣告為虛擬函式,那麼由於物件還未建立,還沒有記憶體空間,更沒有虛擬函式表地址用來呼叫虛擬函式即構造函數了
2、解構函式最好宣告為虛擬函式
首先解構函式可以為虛擬函式,當析構一個指向派生類的基類指標時,最好將基類的解構函式宣告為虛擬函式,否則可以存在記憶體洩露的問題。
如果解構函式不被宣告成虛擬函式,則編譯器實施靜態繫結,在刪除指向派生類的基類指標時,只會呼叫基類的解構函式而不呼叫派生類解構函式,這樣就會造成派生類物件析構不完全。
子類析構時,要呼叫父類的解構函式嗎?
解構函式呼叫的次序時先派生類後基類的。
和建構函式的執行順序相反。
並且解構函式要是virtual的,否則如果用父類的指標指向子類物件的時候,解構函式靜態繫結,不會呼叫子類的析構。
不用顯式呼叫,會自動呼叫
22、靜態繫結和動態繫結的介紹
靜態繫結和動態繫結是C++多型性的一種特性
1)物件的靜態型別和動態型別
靜態型別:物件在宣告時採用的型別,在編譯時確定
動態型別:當前物件所指的型別,在執行期決定,物件的動態型別可變,靜態型別無法更改
2)靜態繫結和動態繫結
靜態繫結:繫結的是物件的靜態型別,函式依賴於物件的靜態型別,在編譯期確定
動態繫結:繫結的是物件的動態型別,函式依賴於物件的動態型別,在執行期確定
只有虛擬函式才使用的是動態繫結,其他的全部是靜態繫結
23、引用是否能實現動態繫結,為什麼引用可以實現
可以。
因為引用(或指標)既可以指向基類物件也可以指向派生類物件,這一事實是動態繫結的關鍵。
用引用(或指標)呼叫的虛擬函式在執行時確定,被呼叫的函式是引用(或指標)所指的物件的實際型別所定義的。
24、深複製和淺複製的區別
深複製和淺複製可以簡單的理解為:如果一個類擁有資源,當這個類的物件發生複製過程的時候,如果資源重新分配了就是深複製;反之沒有重新分配資源,就是淺複製。
25、什麼情況下會呼叫複製建構函式(三種情況)
系統自動生成的建構函式:普通建構函式和複製建構函式(在沒有定義對應的建構函式的時候)
生成一個例項化的物件會呼叫一次普通建構函式,而用一個物件去例項化一個新的物件所呼叫的就是複製建構函式
呼叫複製建構函式的情形:
1)用類的一個物件去初始化另一個物件的時候
2)當函式的引數是類的物件時,就是值傳遞的時候,如果是引用傳遞則不會呼叫
3)當函式的返回值是類的物件或者引用的時候
舉例:
#include
dynamic_cast如果不能轉換返回NULL
dynamic_cast轉為引用型別的時候轉型失敗會拋bad_cast
源類中必須要有虛擬函式,保證多型,才能使用dynamic_cast
延伸文章資訊
- 1面試C/C++ 觀念整理
這裡有些題目是來自網路上MTK面試的C考古題,另外又加入了一些易搞混的觀念,幫自己統整一下,也希望能幫助在求職的讀者,面試的過程真的心很累啊!
- 2【C/C++】【面試】 科技業筆試常考觀念題: 資料型態(data type)
- 3c++ 筆試試題參考.pdf
成功高中101 學年高一上程式語言C++ 期末考筆試試卷班級座號: 選擇題共四十題(每題2.5 分答對給分,答錯不倒扣). #include<iostream> using namespace ...
- 4100条经典C++笔试题目及答案分享 - CSDN博客
100条经典C++笔试题目分享一、C++与C差异(1-18)二、数据类型、关键字(19-37)三、C++面向对象的特性(38-61)四、程序阅读题(62-90)五、编程练习(91-100) ...
- 5面試必備| 常見C++筆試面試題整理 - sa123
編譯階段,g++會呼叫gcc,對於c++程式碼,兩者是等價的,但是因為gcc命令不能自動和C++程式使用的庫聯接,所以通常用g++來完成連結。