日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

二十万字C/C++、嵌入式软开面试题全集宝典三

發布時間:2025/3/15 c/c++ 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二十万字C/C++、嵌入式软开面试题全集宝典三 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

目錄

1、 構造函數析構函數可否拋出異常

2、 類如何實現只能靜態分配和只能動態分配

3、 如果想將某個類用作基類,為什么該類必須定義而非聲明?

4、 什么情況會自動生成默認構造函數?

5、 構造函數的擴展過程?

6、 程序員定義的析構函數被擴展的過程?

7、 構造函數的執行算法?

8、 哪些函數不能是虛函數

9、 虛函數的調用機制

10、 什么是類的繼承?

11、 什么是多繼承

12、 什么是組合?

13、 抽象基類為什么不能創建對象?

14、 純虛函數定義

15、 虛函數與純虛函數的區別在于

16、 類什么時候會析構?

17、 為什么友元函數必須在類內部聲明?

18、 C++ ?向對象的三?特征是:封裝、繼承、多態。

19、 介紹一下C++里面的多態?

20、 C++ 中重載和重寫,重定義的區別


?

1、 構造函數析構函數可否拋出異常

1.C++只會析構已經完成的對象,對象只有在其構造函數執行完畢才算是完全構造妥當。在構造函數中發生異常,控制權轉出構造函數之外。因此,在對象b的構造函數中發生異常,對象b的析構函數不會被調用。因此會造成內存泄漏。

2.用auto_ptr對象來取代指針類成員,便對構造函數做了強化,免除了拋出異常時發生資源泄漏的危機,不再需要在析構函數中手動釋放資源;

3.如果控制權基于異常的因素離開析構函數,而此時正有另一個異常處于作用狀態,C++會調用terminate函數讓程序結束;

4.如果異常從析構函數拋出,而且沒有在當地進行捕捉,那個析構函數便是執行不全的。如果析構函數執行不全,就是沒有完成他應該執行的每一件事情。

2、 類如何實現只能靜態分配和只能動態分配

1.前者是把new、delete運算符重載為private屬性;后者是把構造、析構函數設為protected屬性,再用子類來動態創建;

2.建立類的對象有兩種方式:

1靜態建立,靜態建立一個類對象,就是由編譯器為對象在棧空間中分配內存;

2動態建立,A *p = new A();動態建立一個類對象,就是使用new運算符為對象在堆空間中分配內存。這個過程分為兩步,第一步執行operator new()函數,在堆中搜索一塊內存并進行分配;第二步調用類構造函數構造對象;

3.只有使用new運算符,對象才會被建立在堆上,因此只要限制new運算符就可以實現類對象只能建立在棧上。可以將new運算符設為私有。

3、 如果想將某個類用作基類,為什么該類必須定義而非聲明?

派生類中包含并且可以使用它從基類繼承而來的成員,為了使用這些成員,派生類必須知道他們是什么。

4、 什么情況會自動生成默認構造函數?

1.帶有默認構造函數的類成員對象,如果一個類沒有任何構造函數,但它含有一個成員對象(另一個類的對象是這個類的成員),而后者有默認構造函數,那么編譯器就為該類合成出一個默認構造函數。不過這個合成操作只有在構造函數真正被需要的時候才會發生;如果一個類A含有多個成員類對象的話,那么類A的每一個構造函數必須調用每一個成員對象的默認構造函數而且必須按照類對象在類A中的聲明順序進行;

2.帶有默認構造函數的基類,如果一個沒有任何構造函數的派生類派生自一個帶有默認構造函數基類,那么該派生類會合成一個構造函數調用上一層基類的默認構造函數;

3.帶有一個虛函數的類

4.帶有一個虛基類的類

5.合成的默認構造函數中,只有基類子對象和成員類對象會被初始化。所有其他的非靜態數據成員都不會被初始化。

5、 構造函數的擴展過程?

1.記錄在成員初始化列表中的數據成員初始化操作會被放在構造函數的函數體內,并與成員的聲明順序為順序;

2.如果一個成員并沒有出現在成員初始化列表中,但它有一個默認構造函數,那么默認構造函數必須被調用;

3.如果class有虛表,那么它必須被設定初值;

4.所有上一層的基類構造函數必須被調用;

5.所有虛基類的構造函數必須被調用。

6、 程序員定義的析構函數被擴展的過程?

1.析構函數函數體被執行;

2.如果class擁有成員類對象,而后者擁有析構函數,那么它們會以其聲明順序的相反順序被調用;

3.如果對象有一個vptr,現在被重新定義

4.如果有任何直接的上一層非虛基類擁有析構函數,則它們會以聲明順序被調用;

5.如果任何虛基類擁有析構函數

7、 構造函數的執行算法?

1.在派生類構造函數中,所有的虛基類及上一層基類的構造函數調用;

2.對象的vptr被初始化;

3.如果有成員初始化列表,將在構造函數體內擴展開來,這必須在vptr被設定之后才做;

4.執行程序員所提供的代碼;

8、 哪些函數不能是虛函數

1.構造函數,構造函數初始化對象,派生類必須知道基類函數干了什么,才能進行構造;當有虛函數時,每一個類有一個虛表,每一個對象有一個虛表指針,虛表指針在構造函數中初始化;

2.內聯函數,內聯函數表示在編譯階段進行函數體的替換操作,而虛函數意味著在運行期間進行類型確定,所以內聯函數不能是虛函數;

3.靜態函數,靜態函數不屬于對象屬于類,靜態成員函數沒有this指針,因此靜態函數設置為虛函數沒有任何意義。

4.友元函數,友元函數不屬于類的成員函數,不能被繼承。對于沒有繼承特性的函數沒有虛函數的說法。

5.普通函數,普通函數不屬于類的成員函數,不具有繼承特性,因此普通函數沒有虛函數。

9、 虛函數的調用機制

1.分為靜態綁定(編譯時綁定),動態綁定(運行時綁定);

當某個虛函數通過指針或是引用調用時就會發生動態綁定,具體調用的函數與對象的動態類型相匹配,當一個基類指針指向派生類時,調用的函數是派生類的函數。

2.由于繼承導致對象的指針和引用有兩種不同的狀態,一個是靜態類型,一個是動態類型。

靜態類型:指針和引用聲明時的類型

動態類型:指針和引用實際指向的類型。

10、 什么是類的繼承?

1.類與類之間的關系

has-A包含關系,即成員對象。用以描述一個類由多個部件類構成,實現has-A關系用類的成員屬性表示,即一個類的成員屬性是另一個已經定義好的類;

use-A,一個類使用另一個類,通過類之間的成員函數相互聯系,定義友元或者通過傳遞參數的方式來實現;

is-A,繼承關系,關系具有傳遞性;

2.繼承的相關概念

所謂的繼承就是一個類繼承了另一個類的屬性和方法,這個新的類包含了上一個類的屬性和方法,被稱為子類或者派生類,被繼承的類稱為父類或者基類;

3.繼承的特點

子類擁有父類的所有屬性和方法,子類可以擁有父類沒有的屬性和方法,子類對象可以當做父類對象使用;

4.繼承中的訪問控制

public、protected、private

5.繼承中的構造和析構函數

繼承中的構造:

1子類對象在創建之時會首先調用父類的構造函數

2先執行父類的構造函數再執行子類的構造函數

3父類的構造函數可以被隱式調用或者顯式調用

繼承中的析構:

1執行自身的析構函數

2執行成員變量的析構函數

3執行父類的析構函數

6.繼承中的兼容性原則

凡是基類能解決的問題,公有派生類都可以解決:

1子類對象可以當作父類對象使用

2子類對象可以直接賦值給父類對象

3子類對象可以直接初始化父類對象

4父類指針可以直接指向子類對象

5父類引用可以直接引用子類對象

在替代之后,派生類對象就可以作為基類的對象使用,但是只能使用從基類繼承的成員。

11、 什么是多繼承

多繼承即一個子類可以有多個父類,它繼承了多個父類的特性。

12、 什么是組合?

1.一個類里面的數據成員是另一個類的對象,即內嵌其他類的對象作為自己的成員;創建組合類的對象:首先創建各個內嵌對象,難點在于構造函數的設計。創建對象時既要對基本類型的成員進行初始化,又要對內嵌對象進行初始化。

2.創建組合類對象,構造函數的執行順序:先調用內嵌對象的構造函數,然后按照內嵌對象成員在組合類中的定義順序,與組合類構造函數的初始化列表順序無關。然后執行組合類構造函數的函數體,析構函數調用順序相反。

13、 抽象基類為什么不能創建對象?

抽象類是一種特殊的類,它是為了抽象和設計的目的建立的,它處于繼承層次結構的較上層。

(1)抽象類的定義:稱帶有純虛函數的類為抽象類。

(2)抽象類的作用:抽象類的主要作用是將有關的操作作為結果接口組織在一個繼承層次結構中,由它來為派生類提供一個公共的根,派生類將具體實現在其基類中作為接口的操作。所以派生類實際上刻畫了一組子類的操作接口的通用語義,這些語義也傳給子類,子類可以具體實現這些語義,也可以再將這些語義傳給自己的子類。

(3)使用抽象類時注意:抽象類只能作為基類來使用,其純虛函數的實現由派生類給出。如果派生類中沒有重新定義純虛函數,而只是繼承基類的純虛函數,則這個派生類仍然還是一個抽象類。如果派生類中給出了基類純虛函數的實現,則該派生類就不再是抽象類了,它是一個可以建立對象的具體的類。

抽象類是不能定義對象的。一個純虛函數不需要(但是可以)被定義。

14、 純虛函數定義

一、定義

純虛函數是一種特殊的虛函數,它的一般格式如下:

class <類名>{virtual <類型><函數名>(<參數表>)=0;…};

1.在許多情況下,在基類中不能對虛函數給出有意義的實現,而把它聲明為純虛函數,它的實現留給該基類的派生類去做。這就是純虛函數的作用。

2.純虛函數可以讓類先具有一個操作名稱,而沒有操作內容,讓派生類在繼承時再去具體地給出定義。凡是含有純虛函數的類叫做抽象類。這種類不能聲明對象,只是作為基類為派生類服務。除非在派生類中完全實現基類中所有的純虛函數,否則,派生類也變成了抽象類,不能實例化對象。

二、純虛函數引入原因

1、為了方便使用多態特性,我們常常需要在基類中定義虛擬函數。

2、在很多情況下,基類本身生成對象是不合情理的。例如,動物作為一個基類可以派生出老虎、孔雀等子類,但動物本身生成對象明顯不合常理。為了解決上述問題,引入了純虛函數的概念,將函數定義為純虛函數(方法:virtual ReturnType Function()= 0;)。若要使派生類為非抽象類,則編譯器要求在派生類中,必須對純虛函數予以重載以實現多態性。同時含有純虛函數的類稱為抽象類,它不能生成對象。這樣就很好地解決了上述兩個問題。例如,繪畫程序中,shape作為一個基類可以派生出圓形、矩形、正方形、梯形等,如果我要求面積總和的話,那么會可以使用一個 shape * 的數組,只要依次調用派生類的area()函數了。如果不用接口就沒法定義成數組,因為既可以是circle ,也可以是square ,而且以后還可能加上rectangle,等等.

三、相似概念

1、多態性

指相同對象收到不同消息或不同對象收到相同消息時產生不同的實現動作。C++支持兩種多態性:編譯時多態性,運行時多態性。

a.編譯時多態性:通過重載函數實現

b.運行時多態性:通過虛函數實現。

2、虛函數

虛函數是在基類中被聲明為virtual,并在派生類中重新定義的成員函數,可實現成員函數的動態重載。

3、抽象類

包含純虛函數的類稱為抽象類。由于抽象類包含了沒有定義的純虛函數,所以不能定義抽象類的對象。

15、 虛函數與純虛函數的區別在于

1.純虛函數只有定義沒有實現,虛函數既有定義又有實現;

2.含有純虛函數的類不能定義對象,含有虛函數的類能定義對象;

16、 類什么時候會析構?

1.對象生命周期結束,被銷毀時;

2.delete指向對象的指針時,或delete指向對象的基類類型指針,而其基類虛構函數是虛函數時;

3.對象i是對象o的成員,o的析構函數被調用時,對象i的析構函數也被調用。

17、 為什么友元函數必須在類內部聲明?

因為編譯器必須能夠讀取這個結構的聲明以理解這個數據類型的大小、行為等方面的所有規則。有一條規則在任何關系中都很重要,那就是誰可以訪問我的私有部分。

18、 C++ ?向對象的三?特征是:封裝、繼承、多態。

1、所謂封裝

就是把客觀事物封裝成抽象的類,并且類可以把??的數據和?法只讓信任的類或者對象操作,對不可信的進?信息隱藏。

?個類就是?個封裝了數據以及操作這些數據的代碼的邏輯實體。在?個對象內部,某些代碼或某些數據可以是私有的,不能被外界訪問。通過這種?式,對象對內部數據提供了不同級別的保護,以防?程序中?關的部分意外的改變或錯誤的使?了對象的私有部分。

2、所謂繼承

是指可以讓某個類型的對象獲得另?個類型的對象的屬性的?法。它?持按級分類的概念。繼承是指這樣?種能?:它可以使?現有類的所有功能,并在?需重新編寫原來的類的情況下對這些功能進?擴展。通過繼承創建的新類稱為“?類”或者“派?類”,被繼承的類稱為“基類”、“?類”或“超類”。繼承的過程,就是從?般到特殊的過程。要實現繼承,可以通過“繼承”和“組合”來實現。

繼承概念的實現?式有兩類:

實現繼承:實現繼承是指直接使?基類的屬性和?法??需額外編碼的能?。

接?繼承:接?繼承是指僅使?屬性和?法的名稱、但是?類必需提供實現的能?。

3、所謂多態

就是向不同的對象發送同?個消息,不同對象在接收時會產?不同的?為(即?法)。即?個接?,可以實現多種?法。

多態與?多態的實質區別就是函數地址是靜態綁定還是動態綁定的。如果函數的調?,在編譯器編譯期間就可以確定函數的調?地址,并產?代碼,則是靜態綁定。?如果函數調?的地址不能在編譯器期間確定,需要在運?時才確定,這就屬于動態綁定。

19、 介紹一下C++里面的多態?

多態可以分為靜態多態(重載,模板)和動態多態(覆蓋,虛函數實現)。

lsy注:關于靜態多態,可以看看C++primer這本書,大概在536頁左右。

1、靜態多態其實就是重載,因為靜態多態是指在編譯時期決定調?哪個函數,根據參數列表來決定。基本原理是,編譯器為函數?成符號表時的不同規則,重載只是?種語?特性,與多態?關,與?向對象也?關,但這?是 C++中增加的新規則。

當編譯器遇到一個模板定義時,它并不生成代碼。只有當實例化出模板的一個特定版本時,編譯器才會生成代碼。

2、動態多態是指通過?類重寫?類的虛函數來實現的,因為是在運?期間決定調?的函數,所以稱為動態多態。函數的運行版本由實參決定,在運行時選擇函數的版本,所以稱為動態綁定。執行動態綁定,即運行基類指針指向派生類的對象,并調用派生類的函數。

?般情況下我們不區分這兩個時所說的多態就是指動態多態。

3、動態多態的實現與虛函數表,虛函數指針相關。

虛函數實現原理:虛函數表(存在對象的棧上或堆上)->虛函數指針(常量區)->虛函數(代碼區)。

純虛函數:?virtual int fun() = 0;

擴展:?類是否要重寫?類的虛函數??類繼承?類時, ?類的純虛函數必須重寫,否則?類也是?個虛類,不可實例化。定義純虛函數是為了實現?個接?,起到?個規范的作?,規范繼承這個類的程序員必須實現這個函數。

20、 C++ 中重載和重寫,重定義的區別

1、重載

翻譯?overload,是指同?可訪問區內被聲明的?個具有不同參數列表的同名函數,依賴于C++函數名字的修飾會將參數加在后?,可以是參數類型,個數,順序的不同。根據參數列表決定調?哪個函數,重載不關?函數的返回類型。

2、重寫

重寫翻譯?override,也叫覆蓋。子類重新定義父類中有相同名稱和參數的虛函數(virtual)。在繼承關系之間。C++利用虛函數實現多態。

重寫的特點:

1被重寫的函數不能是static的。必須是virtual的

2重寫函數必須有相同的類型,名稱和參數列表

3重寫函數的訪問修飾符可以不同。盡管父類的virtual方法是private的,派生類中重寫改寫為public,protected也是可以的。

3、重定義(隱藏)

派?類重新定義?類中相同名字的? virtual 函數,參數列表和返回類型都可以不同,即?類中除了定義成 virtual 且完全相同的同名函數才不會被派?類中的同名函數所隱藏(重定義),否則就是重寫了(重寫與重定義的區別)。

總結

以上是生活随笔為你收集整理的二十万字C/C++、嵌入式软开面试题全集宝典三的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。