C++面試題 1-50
1. 面向對象的程序設計思想是什麼?
答:把數據結構和對數據結構進行操作的方法封裝形成一個個的對象。
2. 什麼是類?
答:把一些具有共性的對象歸類後形成一個集合,也就是所謂的類。
3. 對象都具有的兩方面特徵是什麼?分別是什麼含義?
答:對象都具有的特徵是:靜態特徵和動態特徵。
靜態特徵是指能描述對象的一些屬性(成員變量),動態特徵是指對象表現出來的行爲(成員函數)
4. 在頭文件中進行類的聲明,在對應的實現文件中進行類的定義有什麼意義?
答:這樣可以提高編譯效率,因爲分開的話只需要編譯一次生成對應的.obj文件後,再次應用該類的地方,這個類就不會被再次編譯,從而大大的提高了編譯效率。
5. 在類的內部定義成員函數的函數體,這種函數會具備那種屬性?
答:這種函數會自動爲內聯函數,這種函數在函數調用的地方在編譯階段都會進行代碼替換。
6. 成員函數通過什麼來區分不同對象的成員數據?爲什麼它能夠區分?
答:通過this指針指向對象的首地址來區分的。
7. C++編譯器自動爲類產生的四個缺省函數是什麼?
答:默認構造函數,拷貝構造函數,析構函數,賦值函數。
8. 拷貝構造函數在哪幾種情況下會被調用?
答:
1.當類的一個對象去初始化該類的另一個對象時;
2.如果函數的形參是類的對象,調用函數進行形參和實參結合時;
3.如果函數的返回值是類對象,函數調用完成返回時。
9. 構造函數與普通函數相比在形式上有什麼不同?(構造函數的作用,它的聲明形式來分析)
答:構造函數是類的一種特殊成員函數,一般情況下,它是專門用來初始化對象成員變量的。
構造函數的名字必須與類名相同,它不具有任何類型,不返回任何值。
10. 什麼時候必須重寫拷貝構造函數?
答:當構造函數涉及到動態存儲分配空間時,要自己寫拷貝構造函數,並且要深拷貝。
11. 構造函數的調用順序是什麼?
答:1.先調用基類構造函數
2.按聲明順序初始化數據成員
3.最後調用自己的構造函數。
12. 哪幾種情況必須用到初始化成員列表?
答:類的成員是常量成員初始化;
類的成員是對象成員初始化,而該對象沒有無參構造函數。
類的成員爲引用時。
13. 什麼是常對象?
答:常對象是指在任何場合都不能對其成員的值進行修改的對象。
14. 靜態函數存在的意義?
答:靜態私有成員在類外不能被訪問,可通過類的靜態成員函數來訪問;
當類的構造函數是私有的時,不像普通類那樣實例化自己,只能通過靜態成員函數來調用構造函數。
15. 在類外有什麼辦法可以訪問類的非公有成員?
答:友元,繼承,公有成員函數。
16. 什麼叫抽象類?
答:不用來定義對象而只作爲一種基本類型用作繼承的類。
17. 運算符重載的意義?
答:爲了對用戶自定義數據類型的數據的操作與內定義的數據類型的數據的操作形式一致。
18. 不允許重載的5個運算符是哪些?
答:
1. .*(成員指針訪問運算符號)
2. ::域運算符
3. Sizeof 長度運算符號
4. ?:條件運算符號
5. .(成員訪問符)
19. 運算符重載的三種方式?
答:普通函數,友元函數,類成員函數。
20. 流運算符爲什麼不能通過類的成員函數重載?一般怎麼解決?
答:因爲通過類的成員函數重載必須是運算符的第一個是自己,而對流運算的重載要求第一個參數是流對象。所以一般通過友元來解決。
21. 賦值運算符和拷貝構造函數的區別與聯繫?
答:相同點:都是將一個對象copy到另一箇中去。
不同點:拷貝構造函數涉及到要新建立一個對象。
22. 在哪種情況下要調用該類的析構函數?
答:對象生命週期結束時。
23. 對象間是怎樣實現數據的共享的?
答:通過類的靜態成員變量來實現對象間的數據共享。靜態成員變量佔有自己獨立的空間不爲某個對象所私有。
24. 友元關係有什麼特性?
答:單向的,非傳遞的,不能繼承的。
25. 對對象成員進行初始化的次序是什麼?
答:它的次序完全不受它們在初始化表中次序的影響,只有成員對象在類中聲明的次序來決定的。
26. 類和對象之間的關係是什麼?
答:類是對象的抽象,對象是類的實例。
27. 對類的成員的訪問屬性有什麼?
答:public,protected,private。
28.const char *p和char * const p; 的區別
答:
如果const位於星號的左側,則const就是用來修飾指針所指向的變量,即指針指向爲常量;
如果const位於星號的右側,const就是修飾指針本身,即指針本身是常量。
29. 是不是一個父類寫了一個virtual 函數,如果子類覆蓋它的函數不加virtual ,也能實現多態?
答:
virtual修飾符會被隱形繼承的。
virtual可加可不加,子類覆蓋它的函數不加virtual ,也能實現多態。
30. 函數重載是什麼意思?它與虛函數的概念有什麼區別?
答:函數重載是一個同名函數完成不同的功能,編譯系統在編譯階段通過函數參數個數、參數類型不同,函數的返回值來區分該調用哪一個函數,即實現的是靜態的多態性。但是記住:不能僅僅通過函數返回值不同來實現函數重載。而虛函數實現的是在基類中通過使用關鍵字virtual來申明一個函數爲虛函數,含義就是該函數的功能可能在將來的派生類中定義或者在基類的基礎之上進行擴展,系統只能在運行階段才能動態決定該調用哪一個函數,所以實現的是動態的多態性。它體現的是一個縱向的概念,也即在基類和派生類間實現。
31. 構造函數和析構函數是否可以被重載,爲什麼?
答:構造函數可以被重載,析構函數不可以被重載。因爲構造函數可以有多個且可以帶參數,而析構函數只能有一個,且不能帶參數。
32. 如何定義和實現一個類的成員函數爲回調函數?
答:
所謂的回調函數,就是預先在系統的對函數進行註冊,讓系統知道這個函數的存在,以後,當某個事件發生時,再調用這個函數對事件進行響應。
定義一個類的成員函數時在該函數前加CALLBACK即將其定義爲回調函數,函數的實現和普通成員函數沒有區別
33. 虛函數是怎麼實現的?
答:簡單說來使用了虛函數表.
34. 抽象類不會產生實例,所以不需要有構造函數。 錯
35. 從一個模板類可以派生新的模板類,也可以派生非模板類。 對
36. main 函數執行以前,還會執行什麼代碼?
答案:全局對象的構造函數會在main 函數之前執行。
37. 當一個類A 中沒有生命任何成員變量與成員函數,這時sizeof(A)的值是多少,如果不是零,請解釋一下編譯器爲什麼沒有讓它爲零。(Autodesk)
答案:肯定不是零。舉個反例,如果是零的話,聲明一個class A[10]對象數組,而每一個對象佔用的空間是零,這時就沒辦法區分A[0],A[1]…了。
38. delete與 delete []區別:
答:delete只會調用一次析構函數,而delete[]會調用每一個成員的析構函數。
39.子類析構時要調用父類的析構函數嗎?
答:會調用。析構函數調用的次序是先派生類的析構後基類的析構,也就是說在基類的的析構調用的時候,派生類的信息已經全部銷燬了
40. 繼承的優缺點。
1、類繼承是在編譯時刻靜態定義的,且可直接使用,
2、類繼承可以較方便地改變父類的實現。
缺點:
1、因爲繼承在編譯時刻就定義了,所以無法在運行時刻改變從父類繼承的實現
2、父類通常至少定義了子類的部分行爲,父類的任何改變都可能影響子類的行爲
3、如果繼承下來的實現不適合解決新的問題,則父類必須重寫或被其他更適合的類替換。這種依賴關係限制了靈活性並最終限制了複用性。
41. 解釋堆和棧的區別。
答:棧區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。
堆(heap)一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。
42. 一個類的構造函數和析構函數什麼時候被調用,是否需要手工調用?
答:構造函數在創建類對象的時候被自動調用,析構函數在類對象生命期結束時,由系統自動調用。
43. 何時需要預編譯:
答:總是使用不經常改動的大型代碼體。
程序由多個模塊組成,所有模塊都使用一組標準的包含文件和相同的編譯選項。在這種情況下,可以將所有包含文件預編譯爲一個預編譯頭。
44. 多態的作用?
答:主要是兩個:
1. 隱藏實現細節,使得代碼能夠模塊化;擴展代碼模塊,實現代碼重用;
2. 接口重用:爲了類在繼承和派生的時候,保證使用家族中任一類的實例的某一屬性時的正確調用
45. 虛擬函數與普通成員函數的區別?內聯函數和構造函數能否爲虛擬函數?
答案:區別:虛擬函數有virtual關鍵字,有虛擬指針和虛函數表,虛擬指針就是虛擬函數的接口,而普通成員函數沒有。內聯函數和構造函數不能爲虛擬函數。
46. 構造函數和析構函數的調用順序? 析構函數爲什麼要虛擬?
答案:構造函數的調用順序:基類構造函數—對象成員構造函數—派生類構造函數;析構函數的調用順序與構造函數相反。析構函數虛擬是爲了防止析構不徹底,造成內存的泄漏。
47. C++中類型爲private的成員變量可以由哪些函數訪問?
答:只可以由本類中的成員函數和友元函數訪問
48. 請說出類中private,protect,public三種訪問限制類型的區別
答:private是私有類型,只有本類中的成員函數訪問;protect是保護型的,本類和繼承類可以訪問;public是公有類型,任何類都可以訪問.
49. 類中成員變量怎麼進行初始化?
答:可以通過構造函數的初始化列表或構造函數的函數體實現。
50. 在什麼時候需要使用“常引用”?
答:如果既要利用引用提高程序的效率,又要保護傳遞給函數的數據不在函數中被改變,就應使用常引用。
答:把數據結構和對數據結構進行操作的方法封裝形成一個個的對象。
2. 什麼是類?
答:把一些具有共性的對象歸類後形成一個集合,也就是所謂的類。
3. 對象都具有的兩方面特徵是什麼?分別是什麼含義?
答:對象都具有的特徵是:靜態特徵和動態特徵。
靜態特徵是指能描述對象的一些屬性(成員變量),動態特徵是指對象表現出來的行爲(成員函數)
4. 在頭文件中進行類的聲明,在對應的實現文件中進行類的定義有什麼意義?
答:這樣可以提高編譯效率,因爲分開的話只需要編譯一次生成對應的.obj文件後,再次應用該類的地方,這個類就不會被再次編譯,從而大大的提高了編譯效率。
5. 在類的內部定義成員函數的函數體,這種函數會具備那種屬性?
答:這種函數會自動爲內聯函數,這種函數在函數調用的地方在編譯階段都會進行代碼替換。
6. 成員函數通過什麼來區分不同對象的成員數據?爲什麼它能夠區分?
答:通過this指針指向對象的首地址來區分的。
7. C++編譯器自動爲類產生的四個缺省函數是什麼?
答:默認構造函數,拷貝構造函數,析構函數,賦值函數。
8. 拷貝構造函數在哪幾種情況下會被調用?
答:
1.當類的一個對象去初始化該類的另一個對象時;
2.如果函數的形參是類的對象,調用函數進行形參和實參結合時;
3.如果函數的返回值是類對象,函數調用完成返回時。
9. 構造函數與普通函數相比在形式上有什麼不同?(構造函數的作用,它的聲明形式來分析)
答:構造函數是類的一種特殊成員函數,一般情況下,它是專門用來初始化對象成員變量的。
構造函數的名字必須與類名相同,它不具有任何類型,不返回任何值。
10. 什麼時候必須重寫拷貝構造函數?
答:當構造函數涉及到動態存儲分配空間時,要自己寫拷貝構造函數,並且要深拷貝。
11. 構造函數的調用順序是什麼?
答:1.先調用基類構造函數
2.按聲明順序初始化數據成員
3.最後調用自己的構造函數。
12. 哪幾種情況必須用到初始化成員列表?
答:類的成員是常量成員初始化;
類的成員是對象成員初始化,而該對象沒有無參構造函數。
類的成員爲引用時。
13. 什麼是常對象?
答:常對象是指在任何場合都不能對其成員的值進行修改的對象。
14. 靜態函數存在的意義?
答:靜態私有成員在類外不能被訪問,可通過類的靜態成員函數來訪問;
當類的構造函數是私有的時,不像普通類那樣實例化自己,只能通過靜態成員函數來調用構造函數。
15. 在類外有什麼辦法可以訪問類的非公有成員?
答:友元,繼承,公有成員函數。
16. 什麼叫抽象類?
答:不用來定義對象而只作爲一種基本類型用作繼承的類。
17. 運算符重載的意義?
答:爲了對用戶自定義數據類型的數據的操作與內定義的數據類型的數據的操作形式一致。
18. 不允許重載的5個運算符是哪些?
答:
1. .*(成員指針訪問運算符號)
2. ::域運算符
3. Sizeof 長度運算符號
4. ?:條件運算符號
5. .(成員訪問符)
19. 運算符重載的三種方式?
答:普通函數,友元函數,類成員函數。
20. 流運算符爲什麼不能通過類的成員函數重載?一般怎麼解決?
答:因爲通過類的成員函數重載必須是運算符的第一個是自己,而對流運算的重載要求第一個參數是流對象。所以一般通過友元來解決。
21. 賦值運算符和拷貝構造函數的區別與聯繫?
答:相同點:都是將一個對象copy到另一箇中去。
不同點:拷貝構造函數涉及到要新建立一個對象。
22. 在哪種情況下要調用該類的析構函數?
答:對象生命週期結束時。
23. 對象間是怎樣實現數據的共享的?
答:通過類的靜態成員變量來實現對象間的數據共享。靜態成員變量佔有自己獨立的空間不爲某個對象所私有。
24. 友元關係有什麼特性?
答:單向的,非傳遞的,不能繼承的。
25. 對對象成員進行初始化的次序是什麼?
答:它的次序完全不受它們在初始化表中次序的影響,只有成員對象在類中聲明的次序來決定的。
26. 類和對象之間的關係是什麼?
答:類是對象的抽象,對象是類的實例。
27. 對類的成員的訪問屬性有什麼?
答:public,protected,private。
28.const char *p和char * const p; 的區別
答:
如果const位於星號的左側,則const就是用來修飾指針所指向的變量,即指針指向爲常量;
如果const位於星號的右側,const就是修飾指針本身,即指針本身是常量。
29. 是不是一個父類寫了一個virtual 函數,如果子類覆蓋它的函數不加virtual ,也能實現多態?
答:
virtual修飾符會被隱形繼承的。
virtual可加可不加,子類覆蓋它的函數不加virtual ,也能實現多態。
30. 函數重載是什麼意思?它與虛函數的概念有什麼區別?
答:函數重載是一個同名函數完成不同的功能,編譯系統在編譯階段通過函數參數個數、參數類型不同,函數的返回值來區分該調用哪一個函數,即實現的是靜態的多態性。但是記住:不能僅僅通過函數返回值不同來實現函數重載。而虛函數實現的是在基類中通過使用關鍵字virtual來申明一個函數爲虛函數,含義就是該函數的功能可能在將來的派生類中定義或者在基類的基礎之上進行擴展,系統只能在運行階段才能動態決定該調用哪一個函數,所以實現的是動態的多態性。它體現的是一個縱向的概念,也即在基類和派生類間實現。
31. 構造函數和析構函數是否可以被重載,爲什麼?
答:構造函數可以被重載,析構函數不可以被重載。因爲構造函數可以有多個且可以帶參數,而析構函數只能有一個,且不能帶參數。
32. 如何定義和實現一個類的成員函數爲回調函數?
答:
所謂的回調函數,就是預先在系統的對函數進行註冊,讓系統知道這個函數的存在,以後,當某個事件發生時,再調用這個函數對事件進行響應。
定義一個類的成員函數時在該函數前加CALLBACK即將其定義爲回調函數,函數的實現和普通成員函數沒有區別
33. 虛函數是怎麼實現的?
答:簡單說來使用了虛函數表.
34. 抽象類不會產生實例,所以不需要有構造函數。 錯
35. 從一個模板類可以派生新的模板類,也可以派生非模板類。 對
36. main 函數執行以前,還會執行什麼代碼?
答案:全局對象的構造函數會在main 函數之前執行。
37. 當一個類A 中沒有生命任何成員變量與成員函數,這時sizeof(A)的值是多少,如果不是零,請解釋一下編譯器爲什麼沒有讓它爲零。(Autodesk)
答案:肯定不是零。舉個反例,如果是零的話,聲明一個class A[10]對象數組,而每一個對象佔用的空間是零,這時就沒辦法區分A[0],A[1]…了。
38. delete與 delete []區別:
答:delete只會調用一次析構函數,而delete[]會調用每一個成員的析構函數。
39.子類析構時要調用父類的析構函數嗎?
答:會調用。析構函數調用的次序是先派生類的析構後基類的析構,也就是說在基類的的析構調用的時候,派生類的信息已經全部銷燬了
40. 繼承的優缺點。
1、類繼承是在編譯時刻靜態定義的,且可直接使用,
2、類繼承可以較方便地改變父類的實現。
缺點:
1、因爲繼承在編譯時刻就定義了,所以無法在運行時刻改變從父類繼承的實現
2、父類通常至少定義了子類的部分行爲,父類的任何改變都可能影響子類的行爲
3、如果繼承下來的實現不適合解決新的問題,則父類必須重寫或被其他更適合的類替換。這種依賴關係限制了靈活性並最終限制了複用性。
41. 解釋堆和棧的區別。
答:棧區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。
堆(heap)一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。
42. 一個類的構造函數和析構函數什麼時候被調用,是否需要手工調用?
答:構造函數在創建類對象的時候被自動調用,析構函數在類對象生命期結束時,由系統自動調用。
43. 何時需要預編譯:
答:總是使用不經常改動的大型代碼體。
程序由多個模塊組成,所有模塊都使用一組標準的包含文件和相同的編譯選項。在這種情況下,可以將所有包含文件預編譯爲一個預編譯頭。
44. 多態的作用?
答:主要是兩個:
1. 隱藏實現細節,使得代碼能夠模塊化;擴展代碼模塊,實現代碼重用;
2. 接口重用:爲了類在繼承和派生的時候,保證使用家族中任一類的實例的某一屬性時的正確調用
45. 虛擬函數與普通成員函數的區別?內聯函數和構造函數能否爲虛擬函數?
答案:區別:虛擬函數有virtual關鍵字,有虛擬指針和虛函數表,虛擬指針就是虛擬函數的接口,而普通成員函數沒有。內聯函數和構造函數不能爲虛擬函數。
46. 構造函數和析構函數的調用順序? 析構函數爲什麼要虛擬?
答案:構造函數的調用順序:基類構造函數—對象成員構造函數—派生類構造函數;析構函數的調用順序與構造函數相反。析構函數虛擬是爲了防止析構不徹底,造成內存的泄漏。
47. C++中類型爲private的成員變量可以由哪些函數訪問?
答:只可以由本類中的成員函數和友元函數訪問
48. 請說出類中private,protect,public三種訪問限制類型的區別
答:private是私有類型,只有本類中的成員函數訪問;protect是保護型的,本類和繼承類可以訪問;public是公有類型,任何類都可以訪問.
49. 類中成員變量怎麼進行初始化?
答:可以通過構造函數的初始化列表或構造函數的函數體實現。
50. 在什麼時候需要使用“常引用”?
答:如果既要利用引用提高程序的效率,又要保護傳遞給函數的數據不在函數中被改變,就應使用常引用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.