C++虚继承和虚基类详解(一)
多繼承(Multiple Inheritance)是指從多個直接基類中產(chǎn)生派生類的能力,多繼承的派生類繼承了所有父類的成員。盡管概念上非常簡單,但是多個基類的相互交織可能會帶來錯綜復雜的設計問題,命名沖突就是不可回避的一個。
多繼承時很容易產(chǎn)生命名沖突,即使我們很小心地將所有類中的成員變量和成員函數(shù)都命名為不同的名字,命名沖突依然有可能發(fā)生,比如典型的是菱形繼承,如下圖所示:
類 A 派生出類 B 和類 C,類 D 繼承自類 B 和類 C,這個時候類 A 中的成員變量和成員函數(shù)繼承到類 D 中變成了兩份,一份來自 A–>B–>D 這條路徑,另一份來自 A–>C–>D 這條路徑。
在一個派生類中保留間接基類的多份同名成員,雖然可以在不同的成員變量中分別存放不同的數(shù)據(jù),但大多數(shù)情況下這是多余的:因為保留多份成員變量不僅占用較多的存儲空間,還容易產(chǎn)生命名沖突。假如類 A 有一個成員變量 a,那么在類 D 中直接訪問 a 就會產(chǎn)生歧義,編譯器不知道它究竟來自 A -->B–>D 這條路徑,還是來自 A–>C–>D 這條路徑。下面是菱形繼承的具體實現(xiàn):
#include<iostream> using namespace std;//間接基類A class A{ protected:int m_a; }; //直接基類B class B: public A{ protected:int m_b; }; //直接基類C class C: public A{ protected:int m_c; }; //派生類D class D: public B, public C{ public:void seta(int a){ m_a = a; } //命名沖突void setb(int b){ m_b = b; } //正確void setc(int c){ m_c = c; } //正確void setd(int d){ m_d = d; } //正確 public:int m_d; }; int main(){D d;cout<<d.m_d;return 0; }這段代碼實現(xiàn)了上圖所示的菱形繼承,第 25 行代碼試圖直接訪問成員變量 m_a,結果發(fā)生了錯誤,因為類 B 和類 C 中都有成員變量 m_a(從 A 類繼承而來),編譯器不知道選用哪一個,所以產(chǎn)生了歧義。
為了消除歧義,我們可以在 m_a 的前面指明它具體來自哪個類:
void seta(int a){ B::m_a = a; }這樣表示使用 B 類的 m_a。當然也可以使用 C 類的:
void seta(int a){ C::m_a = a; }總結
以上是生活随笔為你收集整理的C++虚继承和虚基类详解(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++多继承时的对象内存模型
- 下一篇: C++虚继承和虚基类详解(二)