好網(wǎng)站目錄汽車軟文廣告
文章目錄
- 一、繼承的二義性
- 1、場景說明 - 繼承的二義性
- 2、繼承中的二義性報錯
- 3、完整代碼示例
- 二、virtual 虛繼承
- 1、虛繼承引入
- 2、虛繼承語法
- 3、代碼示例 - 虛繼承
一、繼承的二義性
1、場景說明 - 繼承的二義性
A 類 是 父類 ,
B 類 和 C 類 繼承 A 類 , 是 子類 ,
D 類 多繼承 B 類 和 C 類 , 是 孫子類 ;
假如 A 類中有 成員變量 x ,
則 子類 B 類 和 C 類 都會繼承該 成員變量 x ,
D 類 多繼承 B 類 和 C 類 , 會 分別從 B 和 C 各自 繼承一個 成員變量 x ;
D 類中 , 從 B , C 兩個父類中繼承自 爺爺類 A 的成員變量 , 會出現(xiàn)二義性 ;
代碼如下 :
#include "iostream"
using namespace std;class A {
public:int x;
};// 子類 B 繼承了父類 A 的 x 成員
class B : public A {
public:int y;
};// 子類 C 繼承了父類 A 的 x 成員
class C : public A {
public:int z;
};// D 多繼承 B 和 C
// 分別從 B 和 C 各自繼承一個來自 A 的成員 x
class D : public B, public C {
public:int k;
};
2、繼承中的二義性報錯
如果強行使用 對象.x
訪問繼承自 A , 會報錯 error C2385: 對“x”的訪問不明確 ;
定義 D 類的對象 d , 如果訪問 繼承自 A 類的 x 成員 , 則會出現(xiàn)二義性 ;
// 定義 D 類對象 dD d;// 訪問 繼承自 A 類的 x 成員出現(xiàn)二義性// 報錯 error C2385: 對“x”的訪問不明確d.x = 40;
完整報錯信息 :
1>------ 已啟動生成: 項目: HelloWorld, 配置: Debug Win32 ------
1>Test.cpp
1>Test.cpp(41,6): error C2385: 對“x”的訪問不明確
1>Test.cpp(41,6): message : 可能是“x”(位于基“A”中)
1>Test.cpp(41,6): message : 也可能是“x”(位于基“A”中)
1>已完成生成項目“HelloWorld.vcxproj”的操作 - 失敗。
========== 生成: 成功 0 個,失敗 1 個,最新 0 個,跳過 0 個 ==========
3、完整代碼示例
代碼示例 :
#include "iostream"
using namespace std;class A {
public:int x;
};// 子類 B 繼承了父類 A 的 x 成員
class B : public A {
public:int y;
};// 子類 C 繼承了父類 A 的 x 成員
class C : public A {
public:int z;
};// D 多繼承 B 和 C
// 分別從 B 和 C 各自繼承一個來自 A 的成員 x
class D : public B, public C {
public:int k;
};int main() {// 定義 D 類對象 dD d;// 訪問繼承自 B 類的 y 成員d.y = 10;// 訪問繼承自 C 類的 z 成員d.z = 20;// 訪問 D 類自己的成員 kd.k = 30;// 訪問 繼承自 A 類的 x 成員出現(xiàn)二義性// 報錯 error C2385: 對“x”的訪問不明確//d.x = 40;// 控制臺暫停 , 按任意鍵繼續(xù)向后執(zhí)行system("pause");return 0;
}
執(zhí)行結(jié)果 :
二、virtual 虛繼承
1、虛繼承引入
在多繼承中 , 如果一個類繼承了多個含有相同基類的派生類 , 就會產(chǎn)生菱形繼承結(jié)構(gòu) ;
這種情況下 , 可能會出現(xiàn)多個不同的基類實例 , 導致重復定義和二義性 ;
為了應(yīng)對上述 繼承的二義性 問題 ,
C++ 語言 使用 " 虛繼承 " 解決 繼承中的 二義性問題 ;
C++ 中的 " 虛繼承 " 是一種解決 多繼承 帶來的 菱形問題(diamond problem)的技術(shù) ;
虛繼承的目的是 確保每個基類只被繼承一次 , 從而避免 重復定義 和 二義性等問題 ;
虛繼承 通過在 派生類 中使用關(guān)鍵字 virtual 來指示基類應(yīng)該被虛繼承 , 虛繼承確保了每個基類只被繼承一次 , 從而避免了重復定義和二義性 ;
在 C++ 中,使用虛繼承的語法是在基類列表中使用 virtual 關(guān)鍵字 ;
2、虛繼承語法
虛繼承語法 : 在 繼承的 訪問限定符 之前 , 添加 virtual 關(guān)鍵字 , 將該繼承行為定義為 " 虛繼承 " ;
class 子類類名 : virtual 訪問限定符 父類類名
{// 子類內(nèi)容
}
下面的 B 類 和 C 類 , 就是 虛繼承 類 A ;
class A {
public:int x;
};// 子類 B 繼承了父類 A 的 x 成員
class B : virtual public A {
public:int y;
};// 子類 C 繼承了父類 A 的 x 成員
class C : virtual public A {
public:int z;
};
3、代碼示例 - 虛繼承
代碼示例 :
#include "iostream"
using namespace std;class A {
public:int x;
};// 子類 B 繼承了父類 A 的 x 成員
class B : virtual public A {
public:int y;
};// 子類 C 繼承了父類 A 的 x 成員
class C : virtual public A {
public:int z;
};// D 多繼承 B 和 C
// 分別從 B 和 C 各自繼承一個來自 A 的成員 x
class D : public B, public C {
public:int k;
};int main() {// 定義 D 類對象 dD d;// 訪問繼承自 B 類的 y 成員d.y = 10;// 訪問繼承自 C 類的 z 成員d.z = 20;// 訪問 D 類自己的成員 kd.k = 30;// 訪問 繼承自 A 類的 x 成員出現(xiàn)二義性// 報錯 error C2385: 對“x”的訪問不明確// 使用 virtual 虛繼承后 , 不會報錯d.x = 40;// 控制臺暫停 , 按任意鍵繼續(xù)向后執(zhí)行system("pause");return 0;
}
執(zhí)行結(jié)果 :