虚基类
虛基類的作用
當一個基類被聲明為虛基類后,即使它成為了多繼承鏈路上的公共基類,最后的派生類中也只有它的一個備份。例如:
class?CBase { };
class CDerive1:virtual public CBase{ };
class CDerive2:virtual public CBase{ };
class CDerive12:public CDerive1,CDerive2{ };
則在類CDerive12的對象中,僅有類CBase的一個對象數據
虛基類的特點:
虛基類構造函數的參數必須由最新派生出來的類負責初始化(即使不是直接繼承);
?????? 虛基類的構造函數先于非虛基類的構造函數執行。
重寫“C++學習筆記(9)——使用范圍運算符解決繼承中的二義性問題 ”中的程序,觀察虛基類的作用 代碼如下: /************************************************************************
*?混合繼承:多基類繼承與多重繼承
************************************************************************/
#include?<IOSTREAM.H>
//基類
class?CBase
{
protected:
????int?a;
public:
????CBase(int?na)
????{
????????a=na;
????????cout<<"CBase?constructor!?";
????}
????~CBase(){cout<<"CBase?deconstructor!?";}
};
//派生類1(聲明CBase為虛基類)
class?CDerive1:virtual?public?CBase
{
public:
????CDerive1(int?na):CBase(na)
????{
????????cout<<"CDerive1?constructor!?";
????}
????
????~CDerive1(){cout<<"CDerive1?deconstructor!?";}
????int?GetA(){return?a;}
};
//派生類2(聲明CBase為虛基類)
class?CDerive2:virtual?public?CBase
{
public:
????CDerive2(int?na):CBase(na)
????{
????????cout<<"CDerive2?constructor!?";
????}
????~CDerive2(){cout<<"CDerive2?deconstructor!?";}
????int?GetA(){return?a;}
};
//子派生類
class?CDerive12:public?CDerive1,public?CDerive2
{
public:
????CDerive12(int?na1,int?na2,int?na3):CDerive1(na1),CDerive2(na2),CBase(na3)
????{
????????cout<<"CDerive12?constructor!?";
????}
????~CDerive12(){cout<<"CDerive12?deconstructor!?";}
};
void?main()
{
????CDerive12?obj(100,200,300);
????//得到從CDerive1繼承的值
????cout<<"?from?CDerive1?:?a?=?"<<obj.CDerive1::GetA();
????//得到從CDerive2繼承的值
????cout<<"?from?CDerive2?:?a?=?"<<obj.CDerive2::GetA()<<endl<<endl;
} 1.?子派生類對象的值: 從上例可以看出,在類CDerived12的構造函數初始化表中,調用了間接基類CBase的構造函數,這對于非虛基類是非法的,但對于虛基類則是合法且必要的。
對于派生類CDerived1和CDerived2,不論是其內部實現,還是實例化的對象,基類CBase是否是它們的虛基類是沒有影響的。受到影響的是它們的派生類CDerived12,因為它從兩條路徑都能到達CBase。 2. 運行結果: 由此可知,其公共基類的構造函數只調用了一次,并且優先于非基類的構造函數調用;并且發現,子派生類的對象obj的成員變量的值只有一個,所以,當公共基類CBase被聲明為虛基類后,雖然它成為CDerive1和CDerive2的公共基類,但子派生類CDerive12中也只有它的一個備份。可以仔細比較與例2的運行結果有什么不同。
轉載于:https://www.cnblogs.com/zfluo/p/5131927.html
總結
- 上一篇: C# Lambda表达式 基础
- 下一篇: 创建守护进程