c++ベース構文:ダミー継承

2757 ワード

虚継承の概念の提出は主にC++多継承の問題を解決するために、最も簡単な例を挙げる.
 
  
class animal{
        public :
              void op()
                  {cout << "hello animal" ;}
 };
class tiger : public animal {
        public :
              void tg()
                  {cout << "this is  tiger" ;}
};
class lion : public animal {
        public :
              void lo()
                  {cout << "this is lion" ;}
};
class liger : public tiger, public lion {
        public :
              void lo()
                  {cout << "this is lion" ;}
};
int main()
{
     class liger  oneliger ;
     liger.op() ; 
}

上のliger.op() ;tigerとlionには親animalのop()操作が含まれているため、誤ったメンバー変数が表示されます.
メモリ内のoneligerオブジェクトのレイアウトが下から下に表示されます.
1、animalのメンバー変数
2、tigerを継承するメンバー変数//op()を含む
3、lionを継承するメンバー変数//op()も含む
4、liger自身のメンバー変数
PS:メモリ内のオブジェクトのレイアウトは、まず虚関数があれば虚表、虚表は関数のポインタ配列を指すポインタ、次にメンバー変数、通常の継承であれば最上位の親のメンバー変数、次に次の親のメンバー変数、そして次の親のメンバー変数の順で、最後は自分のメンバー変数[虚継承逆]です.メンバー関数は、オブジェクト空間に格納されないグローバル関数にコンパイルされ、メンバー関数を呼び出す必要がある場合は、クラス名で対応する関数を見つけ、オブジェクトのthisポインタを関数に渡します.たとえば、このようなコードCTest test;  test.print();コンパイラは内部で:(偽コード)CTest test;CTest_print(&test);//CTestのprint関数変換先:CTest_print(   CTest*   const   this);したがって、これは通常の関数呼び出しと大きく異なりません.実際には関数がオブジェクトを見つけるべきです.つまり、thisポインタに基づいて
上記の多重継承の問題を解決するために、c++では虚継承の概念が提案されている.虚継承とは、子クラスに親クラスのコピーが1部しか残っていないことであり、上のクラスの子にとって、「親クラスのコピーが1部あれば親クラスのコピーを使用し、なければコピーを1部追加する」ということである.
 
  
class animal{
        public :
              void op()
                  {cout << "hello animal" ;}
 };
class tiger : public virtual animal {
        public :
              void tg()
                  {cout << "this is  tiger" ;}
};
class lion : public virtual animal {
        public :
              void lo()
                  {cout << "this is lion" ;}
};
class liger : public tiger, public lion {
        public :
              void lo()
                  {cout << "this is lion" ;}
};
int main()
{
     class liger  oneliger ;
     liger.op() ; 
}

ligerオブジェクトのメモリ内のレイアウトが次のようになります.
4、animalのメンバー変数
3、tigerを継承するメンバー変数//op()を含む
2、lionを継承するメンバー変数//コピーがすでに含まれているので、op()は含まれていません.
1、liger自身のメンバー変数
これにより、メモリにはanimalオブジェクトのコピーが1つしかないので、ぼやけた問題はありません.