C++、ダイヤモンド継承と仮想継承

1. ダイヤモンド継承の基本概念

        ダイヤモンド継承 (ダイヤモンド継承とも呼ばれる) は、共通の基本クラスから複数の中間サブクラスを導出し、次に複数の中間サブクラスから収束サブクラスを導出します。集約サブクラスは、中間サブクラスが共通の基本クラスから継承する複数のメンバーを取得します。

ダイヤモンド継承フォーマット:

                 A       --------公共基类
               /    \
              B      C    ------- 中间子类
               \    /
                  D       --------汇聚子类

例:

 

#include <iostream>
using namespace std;

//封装公共基类 家具 类
class Jiaju
{
private:
    string color;
public:
    //无参构造
    Jiaju() {cout << "家具的无参构造函数" << endl;}

    //有参构造
    Jiaju(string n):color(n)
    {
        cout << "家具的有参构造函数" << endl;
    }
};

//中间子类
//封装 沙发的类
class Sofa:public Jiaju
{
private:
    string sitting;
public:
    //无参构造
    Sofa() {cout << "沙发的无参构造" << endl;}


    //有参构造函数
    Sofa(string s,string c):Jiaju(c),sitting(s)
    {
        cout << "沙发的有参构造" << endl;
    }
    void display()
    {
        cout << sitting << endl;
    }
};


//中间子类
//封装 床 类
class Bed:public Jiaju
{
private:
    string sleep;

public:
    //无参
    Bed() {cout << "床的无参构造" << endl;}

    //有参
    Bed(string s,string c):Jiaju(c),sleep(s)
    {
        cout << "床的有参构造" << endl;
    }
    void display()
    {
        cout << sleep << endl;
    }
};

//汇聚子类
//封装 沙发床类  继承于沙发 和 床
class Sofa_Bed:public Bed,public Sofa
{
private:
    int w;
public:

    //
    Sofa_Bed(){cout << "沙发床的无参构造" << endl;}

    //有参构造
    Sofa_Bed(string sit, string s, int w,string c):Bed(s,c),Sofa(sit,c),w(w)
    {
        cout << "沙发床的有参构造" << endl;
    }
};

int main()
{
//    Sofa_Bed s;
    Sofa_Bed s1("可坐","可躺",123,"pink");

    return 0;
}

ダイヤモンドの継承に関する問題:

        サブクラスを集約すると、パブリック基本クラスから中間サブクラスによって継承された複数のメンバーが取得されるため、スペースが不必要に浪費され、パブリック基本クラスのメンバーも複数回初期化または解放されます。

2. 仮想継承

 仮想継承の役割:

        集約サブクラスには、共通基本クラスから中間サブクラスによって継承されたメンバーのコピーを 1 つだけ保持させることができます。       

 仮想継承の形式:

        中間サブクラスの継承メソッドの前にvirtualを追加

class 类名 : virtual 继承方式 类名   //中间子类
{
    中间子类的拓展;
};

仮想継承を使用する場合の注意事項: 

        中間サブクラスがパブリック基本クラスを仮想的に継承した後、サブクラスの初期化リストを収集し、最初に中間サブクラスのパラメーター化されたコンストラクターを呼び出し、次に中間サブクラスがパブリック基本クラスのパラメーター化されたコンストラクターを呼び出します。ただし、仮想継承後は、中間サブクラスがパブリック基本クラスから継承したパラメーター化されたコンストラクターのコピーが 1 つだけ保持されます。これは、中間サブクラスが継承したパブリック基本クラスのどのコンストラクターが呼び出されるかが不明であることを意味します。デフォルトで呼び出されます。パブリック基本クラスのパラメータなしのコンストラクターです。

        集約サブクラスがパブリック基本クラスのデータ メンバーを初期化したい場合は、パブリック基本クラスのコンストラクターを明示的に呼び出す必要があります。

例: 

#include <iostream>
using namespace std;

//封装公共基类 家具 类
class Jiaju
{
private:
    string color;
public:
    //无参构造
    Jiaju() {cout << "家具的无参构造函数" << endl;}

    //有参构造
    Jiaju(string n):color(n)
    {
        cout << "家具的有参构造函数" << endl;
    }
};

//中间子类
//封装 沙发的类
class Sofa:virtual public Jiaju  //中间子类虚继承公共基类
{
private:
    string sitting;
public:
    //无参构造
    Sofa() {cout << "沙发的无参构造" << endl;}

    //有参构造函数
    Sofa(string s,string c):Jiaju(c),sitting(s)
    {
        cout << "沙发的有参构造" << endl;
    }
    void display()
    {
        cout << sitting << endl;
    }
};

//中间子类
//封装 床 类
class Bed:virtual public Jiaju  //中间子类虚继承公共基类
{
private:
    string sleep;

public:
    //无参
    Bed() {cout << "床的无参构造" << endl;}

    //有参
    Bed(string s,string c):Jiaju(c),sleep(s)
    {
        cout << "床的有参构造" << endl;
    }
    void display()
    {
        cout << sleep << endl;
    }
};

//汇聚子类
//封装 沙发床类  继承于沙发 和 床
class Sofa_Bed:public Bed,public Sofa
{
private:
    int w;
public:
    //
    Sofa_Bed(){cout << "沙发床的无参构造" << endl;}

    //有参构造
    Sofa_Bed(string sit, string s, int w,string c):Jiaju(c),Bed(s,c),Sofa(sit,c),w(w) //需要在汇聚子类中显性调用公共基类的有参构造函数
    {
        cout << "沙发床的有参构造" << endl;
    }
};

int main()
{
//    Sofa_Bed s;
    Sofa_Bed s1("可坐","可躺",123,"pink");
    return 0;
}

おすすめ

転載: blog.csdn.net/weixin_53478812/article/details/132652421