虛基類 虛擬繼承 虛函式?

2021-08-20 11:15:03 字數 1440 閱讀 4271

前幾天師兄想考我什麼是虛基類的時候,我說是因為多重繼承中,如果出現菱形繼承(multiple inheritance diamond),不想要末端派生類有兩份最底層基類的資料的話,就得用虛擬繼承。結果居然被懟了,說我說的啥玩意兒?我還以為我記錯了,實際上是他把虛基類和含有虛函式的基類給混淆了。

今天讀了effective cpp,再總結一下虛基類把,就是被虛擬繼承的基類。虛擬繼承很少用到,因為多重繼承會很複雜,不推薦也不常用。離開了多重繼承,虛擬繼承就完全失去了存在的必要,因為虛擬繼承會降低效率、占用更多的空間。

效率上,在通過繼承類物件訪問虛基類物件中的成員(包括資料成員和函式成員)時,都必須通過某種間接引用來完成,這樣會增加引用定址時間(就和虛函式一樣),其實就是調整this指標以指向虛基類物件,只不過這個調整是執行時間接完成的。

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

考慮四種情況在vs2013(win32)中的sizeof(a),sizeof(b)

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

class a           class a             class a              class a

;              };                  char x;              char x;

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

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

};                };

前兩種情況,a的大小是虛函式表指標所以sizeof(a)=4,後兩種情況,多了個佔1位元組的char,記憶體對齊後,sizeof(a)=8。

派生類裡面要包含基類的空間,虛繼承、虛函式表分別需要乙個指標,所以第一種情況sizeof(b)=12,第二種情況是8,第三種情況是16,第四種情況是12。

虛函式說白了就是一種動態的聯編,主要是用於基類指標指向派生類物件的時候,能動態地選擇對應的虛函式。虛函式相當於繼承了乙個介面,虛函式可以是純虛函式,純虛函式也可以有定義(有定義的純虛函式,技能強制要求派生類重定義,防止誤用基類的操作,又能提供預設操作,不過需要在派生類中顯示呼叫base::virtualfun()),這都是後話,反正跟虛基類是另乙個概念了。

明白師兄的意思,但是從學術上來講還是要嚴謹一點,虛基類和帶虛函式的基類不一樣。

虛擬繼承,虛基類

文章出處 http blog.csdn.net skylor archive 2009 03 26 4025698.aspx 虛擬繼承與虛基類實際上是說了同一件事,只是不同的書表達不同,在這裡還是推薦虛擬繼承這種說法 因為總有人問虛基類是什麼,這裡可以解釋為虛基類就是虛擬繼承,一種繼承的方式,有的書...

C 虛基類 虛擬繼承

虛基類建構函式的引數必須由最新派生出的類負責初始化,即使不是直接繼承,示例程式的虛基類的建構函式只執行一次 include include include using namespace std class base class base1 virtual public base class bas...

虛基類與虛擬繼承

虛擬繼承 顧名思義就是繼承了但不給開闢空間 class b0 此段 中b0就是虛基類 public int m class b1 virtual public b0 b1虛擬繼承b0 public int n class b2 virtual public b0 b2虛擬繼承b0 public in...