c++ベース構文:ダミー継承
2757 ワード
虚継承の概念の提出は主にC++多継承の問題を解決するために、最も簡単な例を挙げる.
上の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部追加する」ということである.
ligerオブジェクトのメモリ内のレイアウトが次のようになります.
4、animalのメンバー変数
3、tigerを継承するメンバー変数//op()を含む
2、lionを継承するメンバー変数//コピーがすでに含まれているので、op()は含まれていません.
1、liger自身のメンバー変数
これにより、メモリにはanimalオブジェクトのコピーが1つしかないので、ぼやけた問題はありません.
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つしかないので、ぼやけた問題はありません.