C 中的虛擬繼承

2021-06-25 08:03:47 字數 2449 閱讀 3715

1.為什麼要引入虛擬繼承

虛擬繼承是多重繼承中特有的概念。虛擬基類是為解決多重繼承而出現的。如:類d繼承自類b1、b2,而類b1、b2都繼承自類a,因此在類d中兩次出現類a中的變數和函式。為了節省記憶體空間,可以將b1、b2對a的繼承定義為虛擬繼承,而a就成了虛擬基類。實現的**如下:

class a

class b1:public virtual a;

class b2:public virtual a;

class d:public b1,public b2;

虛擬繼承在一般的應用中很少用到,所以也往往被忽視,這也主要是因為在c++中,多重繼承是不推薦的,也並不常用,而一旦離開了多重繼承,虛擬繼承就完全失去了存在的必要因為這樣只會降低效率和占用更多的空間。

2.引入虛繼承和直接繼承會有什麼區別呢

由於有了間接性和共享性兩個特徵,所以決定了虛繼承體系下的物件在訪問時必然會在時間和空間上與一般情況有較大不同。

2.2空間:由於共享所以不必要在物件記憶體中儲存多份虛基類子物件的拷貝,這樣較之多繼承節省空間。虛擬繼承與普通繼承不同的是,虛擬繼承可以防止出現diamond繼承時,乙個派生類中同時出現了兩個基類的子物件。也就是說,為了保證這一點,在虛擬繼承情況下,基類子物件的布局是不同於普通繼承的。因此,它需要多出乙個指向基類子物件的指標。

3.筆試,面試中常考的c++虛擬繼承的知識點

第一種情況:         第二種情況:          第三種情況            第四種情況:

class a           class a              class a              class a

;              };                  char x;              char x;

class b:publicvirtuala   class b :public a           };                };

;              };                  virtual void foo();        virtual void foo();

};                };

如果對這四種情況分別求sizeof(a),  sizeof(b)。結果是什麼樣的呢?下面是輸出結果:(在vc6.0中執行)

第一種:4,12 

第二種:4,4

第三種:8,16

第四種:8,8

想想這是為什麼呢?

因為每個存在虛函式的類都要有乙個4位元組的指標指向自己的虛函式表,所以每種情況的類a所佔的位元組數應該是沒有什麼問題的,那麼類b的位元組數怎麼算呢?看「第一種」和「第三種」情況採用的是虛繼承,那麼這時候就要有這樣的乙個指標vptr_b_a,這個指標叫虛類指標,也是四個位元組;還要包括類a的位元組數,所以類b的位元組數就求出來了。而「第二種」和「第四種」情況則不包括vptr_b_a這個指標,這回應該木有問題了吧。

4.c++過載、覆蓋、隱藏的區別和執行方式

既然說到了繼承的問題,那麼不妨討論一下經常提到的過載,覆蓋和隱藏

4.1成員函式被過載的特徵

(1)相同的範圍(在同乙個類中); 

(2)函式名字相同; 

(3)引數不同; 

(4)virtual 關鍵字可有可無。 

4.2「覆蓋」是指派生類函式覆蓋基類函式,特徵是:

(1)不同的範圍(分別位於派生類與基類); 

(2)函式名字相同; 

(3)引數相同; 

(4)基類函式必須有virtual 關鍵字。 

4.3「隱藏」是指派生類的函式遮蔽了與其同名的基類函式,特徵是:

(1)如果派生類的函式與基類的函式同名,但是引數不同,此時,不論有無virtual關鍵字,基類的函式將被隱藏(注意別與過載混淆)。 

(2)如果派生類的函式與基類的函式同名,但是引數相同,但是基類函式沒有virtual 關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆)。

小結:說白了就是如果派生類和基類的函式名和引數都相同,屬於覆蓋,這是可以理解的吧,完全一樣當然要覆蓋了;如果只是函式名相同,引數並不相同,則屬於隱藏。

4.4 三種情況怎麼執行:

4.4.1 過載:看引數。

4.4.2 隱藏:用什麼就呼叫什麼。

4.4.3 覆蓋:呼叫派生類。

c 繼承中的覆蓋,隱藏,虛擬繼承

首先,宣告一點,覆蓋和隱藏是基於繼承來討論的 至於過載貌似和繼承沒有太大聯絡,所謂過載就是同一函式名,不同的引數列表 型別或個數 這裡不做討論。1 覆蓋 特點 1 父類的成員函式是虛函式,即在成員函式前加上virtual關鍵字 2 子類的同名成員函式和父類的完全相同,即引數和返回值型別完全一樣 滿足...

C 虛擬繼承中的物件模型

最近,從師兄那裡聽到一道據說是某國內知名 it公司的面試題,有關 c 虛擬繼承的。include using namespace std class t class a virtual public t class b virtual public t class c public a,public...

C 虛擬繼承

就是為了解決面相物件中繼承結構中可怕的菱形結構 下面是別人的,看看就懂了。從意義上來看,乙個sleepersofa沒有沙發和床兩種重量,如此的繼承不是真實的現實世界描述。進一步分析可得,床和沙發都是家具的一種,凡家具都有重量,所以通過分解來考察其關係,如圖17 2所示。圖17 2 床和沙發的分解 c...