1、C語言與C++語言的區別?
C語言是面相過程的語言,而C++是面相對象的程序設計語言。
2、解釋類和對象的關系,並舉例說明
類是對象的類型,對象是類的具體實例。如學生就是一個類型,而學生張三就是一個具體的對象。
3、一個類由幾部分成員構成?
成員變量和成員函數
4、構造函數有什麼作用?
構造對象時對對象初始化
5、簡述構造函數的特點?
-1必須公有
-2構造函數名和類名一致
-3無返回值
-4構造函數可以接受參數用來初始化類的數據成員
6、什麼是默認構造函數?
默認構造函數分兩種:1構造函數不帶參數;2構造函數帶參數但參數都有默認值。
7、程序員在定義類時是否必須寫一個構造函數,為什麼?
不是必須,如果程序員一個構造函數都沒寫,編譯器將提供一個空的默認構造函數,他不會對數據成員進行初始化。一旦程序員提供了構造函數,編譯器將不提供默認構造函數。
8、什麼是函數重載,並舉例說明?
-1參數列表不同(a參數個數不同;b參數類型不同)
-2僅僅返回值不同不能算函數重載。
eg:Thing();
Thing(int a);
Thing(int a, int b);
9、什麼是初始化列表,有什麼作用,什麼情況下必須使用初始化列表?
在構造函數的函數頭,對類的成員變量進行初始化。
初始化列表優勢:1效率高;2有一些類型的成員變量,只能使用初始化列表的方式初始化,如const,引用
10、設麼是const成員函數,他有什麼作用,通常情況下那些函數會是const成員函數?
const成員函數:函數體內,不能別改這個類的成員變量的值。
void printPoint()const;一般用於print,get等函數。
作用:增加程序的健壯性(魯棒性)
11、析構函數有什麼作用,析構函數在什麼情況下會被調用?
析構函數用於釋放對象所占用的資源空間,當一個對象被銷毀時會自動調用析構函數。
12、一個類是否必須要定義一個析構函數,什麼情況下必須要寫析構函數?
如果類的成員時基本數據類型時則不需要寫析構函數,但當類的成員有指針變量只想堆空間,即動態分配內存時,必須顯示的銷毀分配的對上的空間,用delete回收指針指向的內存空間。避免內存洩漏。
13、什麼時淺拷貝?淺拷貝會產生什麼問題?
可以把一個對象賦值給另一個對象,對象的每個成員的值,將一對一的拷貝到新的對象。這種拷貝叫邏輯拷貝,或淺拷貝。但是,如果對象含有指針成員變量,而指針變量又指向堆上空間,將只拷貝指針成員變量本身的值,造成兩個對象的指針指向同一塊對上的內存空間,刪除對象時造成二次刪除。
14、什麼是函數鏈,使用函數鏈需要注意什麼問題?
用一個函數調用另一個函數,如middle(p,q)。print();使用函數鏈時必須注意前一個函數的返回值必須是對象。
15、能否返回一個指向局部變量的指針或引用,為什麼?
不能,局部變量在函數結束後自動被系統回收,那麼指針將會變成野指針,引用將會變成無效引用,但值程序會有意想不到的結果發生。
16、Point middle(const Point & p1,const Point & p2);解釋該函數的參數中加const和&的作用是什麼?
加&的作用時為了避免拷貝,可與你節省內存空間,提高效率,加const時為了避免自函數體內修改形參的值。
17、什麼時this指針,解釋對象調用函數時傳遞參數的過程。
每個對象都隱式的包含了一個成員變量,名叫this。this是一個指針,指向對象自己。即this指針裡保存的地址,就是對象自己在內存裡的地址。
當一個類的對象調用成員函數時會默認將該對象傳遞給該函數,在函數體內不直接使用對象名,而是使用this指針,即this指針是指向該對象,指向調用者,誰調用該函數,this指針就指向誰。
18、靜態局部變量和局部變量的區別,靜態局部變量和靜態全局變量的區別(生命周期和 作用范圍分析)
局部變量存儲在棧中,作用域為函數體內,生命周期:函數結束後被系統回收,
靜態局部變量放在靜態存儲區,作用域為函數體內,生命周期:函數返回後,靜態局部變量的內存空間不會被回收:當下一次調用函數時,靜態局部變量依然保持上一次調用退出時的值。
靜態全局變量也存儲在靜態存儲區,作用域為從聲明到整個文件結束,生命周期:整個程序運行期間。
19、簡述類的普通成員變量和靜態成員變量的區別。
某一個具體對象,對於非靜態成員來說,每個對象都有一個特定值,每個對象都為自己都為自己的非靜態成員,在內存裡保留一個位置。而靜態成員,整個類只有一份copy,不需要每個對象都保留一份copy,所有的對象都共享這塊空間。
20、調用類的靜態成員的兩種方式是什麼?
a、類名::靜態成員名
b、對象.靜態成員名
21、使用類的靜態成員變量時需要注意什麼問題。
類的靜態成員變量要在類體之外(作用域::)進行初始化。
22、類的靜態成員函數和普通成員函數的區別
類的靜態成員函數,不能訪問非靜態成員變量和非靜態成員函數。普通成員函數,既可以訪問靜態成員,也可以訪問非靜態成員。
23、友元函數有什麼作用
友元函數可以訪問類的私有成員。
24、使用友元函數的優缺點是什麼?
友元可以改善性能,但是破環了封裝。
25、什麼是操作符重載?
用以存在的操作符其它類型的操作數(對象),稱為操作符重載,操作符重載的目的就是讓一些操作符可以直接操作對象。
26、為什麼要實現兩個版本的下標重載?
const對象只能調用const成員函數,故要實現const版本的下標重載,而非const版本的下標重載用於寫操作。
27、簡述淺拷貝與深拷貝的區別
淺拷貝指的是兩個對象的指針成員指向同一塊空間,而深拷貝是讓兩個對象的指針成員指向格子的空間。
28、賦值運算符重載的五步?
-避免自賦值,避免把一個對象賦值給它自己
-釋放掉指針成員已經指向的內存,避免內存洩漏
-為指針成員開辟新內存空間
-內容本身的copy
-返回*this
29、簡述C++中的繼承
子類繼承父類所有的成員,但不包括構造函數、析構函數和賦值運算符重載,子類繼承父類後子類的成員有兩部分:一是繼承自父類的成員;二是子類自己擴展的成員。
30、C++de空類,編譯器會默認提供哪些成員函數?
一個卻生的構造函數、一個拷貝構造函數、一個析構函數、一個賦值運算符
31、C++中什麼時候會調用拷貝構造函數?
通過拷貝一個已有對象,來創建一個新的對象。
-classT objet(another__object);把一存在的對象,作為新聲明對象的構造函數的參數。
-classT object = another_object;聲明一個對象,並用賦值表達式,用一個已有對象來初始化它。
-用傳值的方式,從函數返回一個對象,也將調用拷貝構造函數。
32、子類繼承父類後,子類的成員包括幾部分?
子類繼承父類後子類的成員有兩部分,一是繼承自父類的成員;二是子類自己擴展的成員。
33、什麼是函數重寫?
子類可以自己實現與父類成員函數原型相同(函數名、參數列表)的成員函數,稱為重寫。
34、子類重寫父類的函數後,能否用子類對象調用到被覆蓋的父類版本的函數?
可以,在子類中調用被覆蓋的父類版本的函數時,在函數名前加 父類類名::
35、自類能否直接訪問父類的“私有”成員,有幾種方式可以訪問到該“私有”成員?
-一是通過繼承自父類的公有成員函數來訪問繼承自父類的私有成員
-二是將父類的私有成員改為protected成員
36、簡述public、protected、private三種繼承方式的區別。
-私有繼承(private):子類中所有自稱子父類的成員(包括成員變量、成員函數),都變成私有成員。
-保護繼承(protected):繼承自父類的public成員,變成子類的protected成員;而繼承自父類的protected和private成員,訪問權限保持不變。
-公有繼承(public):所有繼承自父類的成員,訪問權限都保持不變。
37、類的成員函數中那些不能是虛函數?
靜態成員函數,內聯成員函數,構造函數
38、繼承有什麼好處,什麼情況下會使用到繼承?
-類之間有自然的繼承關系
-代碼復用
-使代碼修改更容易,只需要修改父類,子類會隨之改變。
39、兩個類之間相互交互的方式有幾種,分別是什麼?
-繼承
-組合類
40、簡述把子類對象當做父類對象使用的三種情況
-把子類對象賦值給父類對象
-父類引用指向子類對象
-父類指針指向子類對象
41、能否把父類對象當做子類對象來使用,為什麼?
不能,因為子類有自己擴展的成員。
42、什麼是向下轉型,什麼情況下才能使用向下轉型?
把一個實際指向子類的父類指針,顯示的轉型成子類指針,就可以通過這個子類指針,調用子類擴展的成員。向下轉型具有潛在的危險,即父類指針實際上沒有指向程序員要把它轉換成的那種子類的對象。
43、使用虛函數的目的是什麼?
虛函數目的:期望父類指針(或引用),不管指向父類還是子類,在調用override函數時,可以反應對象真是情況。
44、如何使用指向子類對象的父類指針或引用調用子類版本的函數?
-向下轉型
-虛函數
45、繼承時為什麼父類的析構函數必須為虛析構
如果父類的析構不是虛析構則當(用delete)刪除一個指向子類對象的父類指針時,則將調用父類版本的析構函數,子類只釋放了來自於父類的那部分成員變量,而沒有釋放子類擴展的成員變量,造成內存洩漏。
46、什麼時動態綁定,有什麼好處?
虛函數被調用的時候到底調用那個版本,在變異的時候無法確定,只有在執行時才能確定稱為動態綁定。動態綁定使得程序可以照顧到未來增加的代碼,比如創建一個新的子類,在子類中覆蓋了父類的虛函數。用之前的父類指針,依然可以正確的調用到新子類裡的函數,而無需對舊代碼進行更改。
47、什麼是多態?
多態:用父類指針or引用,統一操作各種子類對象。父類指針或引用有多重表現形態。
48、簡述虛函數調用的過程?
在每個虛函數的對象裡,添加一個虛指針成員變量,虛指針指向虛函數表,首先通過虛函數指針找到虛函數表,虛函數表中存放的是虛函數的指針(地址),然後再通過虛函數指針找到虛函數。
49、什麼是純虛函數,什麼是抽象類、什麼是虛函數
純虛函數:虛函數只有聲明沒有實現
抽象類:有純虛函數的類較抽象類
虛函數:virtual關鍵字。
50、為什麼要引入抽象基類和純虛函數?
抽象類提供了不同種類對象的一個通用接口。父類聲明子類實現
51、子類是否必須實現抽象基類中的所有的純虛函數,為什麼?
子類必須實現抽象基類中的所有純虛函數。否則,子類依然是抽象類。
52、多重繼承時會產生什麼問題?
同名函數或變量,菱形繼承時候有兩份祖先類的成員。
53、菱形繼承如何消除向上繼承產生的二義性問題
-虛繼承,1:直接繼承祖先的額兩個類,在繼承時加virtual;
2:通過多重繼承而來的那個子類(孫子輩),在構造是,要調用祖先的構造函數。
孫子類的派生類,直接繼承祖先類的成員,在繼承兩個父類各自拓展的成員。
54、什麼是名字空間,有什麼作用?
-名字空間定義了全局標識符的作用域。
-名字空間作用:避免同一個程序中,不同文件裡的全局標識符的沖突。
55、什麼是函數模版,函數模版有什麼好處?有很多函數僅僅是參數類型不同,但是實現過程很相似。在C++裡,我們可以寫一個通用函數,使用非實例化的參數類型,該函數被調用時進行實例化。這種函數稱為函數模版。
56、簡述靜態強制轉換和動態強制轉換的區別static__cast:靜態轉型。不管父類指針是否真的指向子類對象,一律把指針轉型後返回。轉型不保證安全。
dynamic_cast:動態類型轉換。把父類指針轉型成子類指針,如果轉型成功(即父類指針的確指向子類對象),返回子類對象地址;如果轉型失敗,返回null。即轉型是安全的。
57、聲明一個string類的對象string s(“Helloworld”);其中s[20]和s.at(20)的區別?
s.at(20)會自動拋出異常。
58、STL中有哪幾大類容器,有什麼區別?
-順序容器&關聯容器
1.元素存儲的順序不同
順序容器:按照插入位置存儲
關聯容器:按鍵本身的值的大小來排列(和插入順序無關)。
2.存取元素的方式不同
順序容器:通過元素在容器裡的位置(如:下標)存取;
關聯容器:通過鍵(key)存取元素(不關心位置)。