關於C 中的虛擬繼承的一些總結

2022-04-28 07:06:09 字數 2022 閱讀 6334

虛擬繼承是多重繼承中特有的概念。虛擬基類是為解決多重繼承而出現的。如:類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.1時間:在通過繼承類物件訪問虛基類物件中的成員(包括資料成員和函式成員)時,都必須通過某種間接引用來完成,這樣會增加引用定址時間(就和虛函式一樣),其實就是調整this指標以指向虛基類物件,只不過這個調整是執行時間接完成的。

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

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

class a           class a             class a              class a

;              };                  char x;              char x;

class b:public virtual a   class b :public a        };                };

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

};                };

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

想想這是為什麼呢?

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

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

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

(2)函式名字相同;

(3)引數不同;

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

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

(2)函式名字相同;

(3)引數相同;

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

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

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

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

4.4.1 過載:看引數。

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

4.4.3 覆蓋:呼叫派生類。

from:

關於C 中的虛擬繼承的一些總結

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

關於C 中的虛擬繼承的一些總結

關於c 中的虛擬繼承的一些總結 1.為什麼要引入虛擬繼承 虛擬繼承是多重繼承中特有的概念。虛擬基類是為解決多重繼承而出現的。如 類d繼承自類b1 b2,而類b1 b2都繼承自類a,因此在類d中兩次出現類a中的變數和函式。為了節省記憶體空間,可以將b1 b2對a的繼承定義為虛擬繼承,而a就成了虛擬基類...

關於C 中的虛擬繼承的一些總結

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