C 虛繼承之小議

2022-08-04 07:36:11 字數 2422 閱讀 4378

c++虛繼承的作用

c++虛繼承可以防止多重繼承產生的二義性問題。

虛繼承,就是在被繼承的類前面加上virtual關鍵字,這時被繼承的類稱為虛基類,如下面**中的base類。虛繼承在多重繼承的時可以防止二義性。

class base

class derived1 : virutal public base

class derived2 : virtual public base

class derived3 : public derived1, public derived2

以上的**如果用到了base中的某個成員變數就不會產生二義性。和#progma once在標頭檔案中的作用類似。請看下面的例子:

#include

using namespace std;

class parent

public:

int p;                                           // p將會被所有的子類繼承,也將是二義性的根源

inline parent()

p = 10;

class child1 : public parent

public:

int c1;

inline child1()

p = 12;                           // p在子類child1中被賦值為12

c1 = 12;

class child2 : public parent

public:

int c2;

inline child2()

p = 13;                          // p在子類child2中被賦值為13

c2 = 13;

class grandchild : public child1, public child2

public:

int grandchild;

// p顯然也存在於grandchild中,但是到底是12,還是13呢?這就產生了二義性

inline grandchild()

grandchild = 14;

int main(void)

grandchild* pgc = new grandchild();

cout << pgc->p << endl;

return 0;

上面程式是不能通過編譯的,編譯器輸出的錯誤資訊如下:

…: error c2385: 'grandchild::p' is ambiguous

…: warning c4385: could be the 'p' in base 'parent' of base 'child1' of class 'grandchild'

…: warning c4385: or the 'p' in base 'parent' of base 'child2' of class 'grandchild'

正如編譯器告訴我們的那樣,grandchild::p是模稜兩可,它被child1繼承了即child1中包含了乙個parent subobject,也被child2繼承了即child2中也包含了乙個parent suboject,然後grandchild又同時繼承了child1和child2,根據「derived class中要保持base class的完整原樣性原則」,因此grandchild包含了兩個parentobject。所以當pgc->p時,編譯器根本無法確定是呼叫child1::p還是child2::p,由此邊產生了模稜兩可的情形。怎麼解決這樣的問題呢?答案就是用虛繼承或者叫虛基類的方式。

在上面的示例程式中做如下改動:

class child1 : public parent       ->     class child1 : virtual public parent

class child2 : public parent      ->      class child2 : virtual public parent

grandchild的定義維持不變:

class grandchild : public child1, public child2

做了上述改動後,即增加了兩個virtual關鍵字,再編譯就不會出現ambiguous之類的錯誤了。這是因為加上了virtual關鍵字後,就可以保證parent suboject在grandchild中只存在乙份,從而消除了ambiguity。上面修改後的程式執行結果是13,這說明child2類的那個p起了作用,如果grandchild的定義寫成:

class grandchild : public child2, public child1

那麼執行結果將是12。

上面的試驗結果表面,在多重繼承的時候,如果父類中有同名的成員變數(類似這篇文章中談及的例子),為了防止二義性,一般要採用虛繼承的方式,並且最右邊的基類中的那個成員變數會出現在派生類物件中。

C 虛繼承和虛繼承

虛繼承是在多繼承中為了解決衝突而技術。學術一點來說,是指乙個指定的基類,在繼承體系結構中,將其成員資料例項共享給也從這個基類直接或間接派生的其他類。虛繼承非常有用,可以避免多繼承的歧義和多重拷貝。考慮有如下繼承結構。b和c繼承a,d多繼承b c,我們看以下 class a class b publi...

c 學習之繼承篇(多重繼承之虛繼承)

虛繼承 是物件導向程式設計中的一種技術,是指乙個指定的基類,在繼承體系結構中,將其成員資料例項共享給也從這個基型別直接或間接派生的其它類。形式 在繼承定義中包含了virtual關鍵字的繼承關係,如下圖中,類a就叫做虛基類。虛擬繼承是多重繼承中的菱形繼承所特有的概念。虛擬基類是為解決多重繼承而出現的。...

C 之菱形繼承與虛繼承 含虛函式

物件導向的三大特徵 封裝,多型,繼承 前面我們已經講了繼承的一些知識點,在這基礎上,我們講的時候再涉獵一些多型的只是。下面我們先接著上次講有虛函式的菱形虛繼承 首先什麼是虛函式。虛函式 在類裡面,函式前面有virtual關鍵字的成員函式就是虛函式。塊 class base base virtual ...