1. 程式人生 > >3.10 C++虛基類 虛繼承

3.10 C++虛基類 虛繼承

set http turn () virt public virtual 這樣的 rtu

參考:http://www.weixueyuan.net/view/6367.html

總結:  

  本例即為典型的菱形繼承結構,類A中的成員變量及成員函數繼承到類D中均會產生兩份,這樣的命名沖突非常的棘手,通過域解析操作符已經無法分清具體的變量了。為此,C++提供了虛繼承這一方式解決命名沖突問題。虛繼承只需要在繼承屬性前加上virtual關鍵字。

  在多繼承時很容易產生命名沖突問題,如果我們很小心地將所有類中的成員變量及成員函數都命名為不同的名字時,命名沖突依然有可能發生,比如非常經典的菱形繼承層次。類A派生出類B和類C,類D繼承自類B和類C,這個時候類A中的成員變量和成員函數繼承到類D中變成了兩份

,一份來自A派生B然後派生D這一路,另一份來自A派生C然後派生D這一條路。

技術分享


例1:

class A
{
public:
    void setx(int a){x = a;}
    int getx(){return x;}
private:
    int x;
};

class B: public A
{
public:
    void sety(int a){y = a;}
    int gety(){return y;}
private:
    int y;   
};

class C: public A
{
public:
    void setz(int a){z = a;}
    
int getz(){return z;} private: int z; }; class D: public B, public C { //...... };

本例即為典型的菱形繼承結構,類A中的成員變量及成員函數繼承到類D中均會產生兩份,這樣的命名沖突非常的棘手,通過域解析操作符已經無法分清具體的變量了。為此,C++提供了虛繼承這一方式解決命名沖突問題。虛繼承只需要在繼承屬性前加上virtual關鍵字。

例2:

#include <iostream>
using namespace std;

class A
{
public:
    void
setx(int a){x = a;} int getx(){return x;} private: int x; }; class B: virtual public A { public: void sety(int a){y = a;} int gety(){return y;} private: int y; }; class C: virtual public A { public: void setz(int a){z = a;} int getz(){return z;} private: int z; }; class D: public B, public C { //...... }; int main() { D test; test.setx(10); cout<<test.getx()<<endl; return 0; }

在本例中,類B和類C都是繼承類A都是虛繼承,如此操作之後,類D只會得到一份來自類A的數據。在本例的主函數中,定義了類D的對象test,然後通過該對象調用從類A間接繼承來的setx和getx成員函數,因為B和C繼承自類A采用的是虛繼承,故通過D調用setx和getx不會有命名沖突問題,因為D類只得到了一份A的數據。

3.10 C++虛基類 虛繼承