c+++基礎文法:虚継承
虚継の概念の提出は主にC++の継承問題を解決するためで、一番簡単な例を挙げます。
2、タイガーを引き継ぐメンバー変数 //opを含む()
3、lionを継承するメンバー変数 / /op()も含まれています
4、liger自体のメンバー変数
PS:オブジェクトのメモリ内のレイアウトは、まず虚関数があれば虚表、虚表は関数ポインタ配列のポインタを指します。そして、メンバー変数です。普通に継承されている場合は、最初に一番根父類のメンバー変数です。次に次父類メンバー変数です。順番に最後に自分のメンバー変数です。メンバー関数は、大域関数としてコンパイルされ、オブジェクト空間には記憶されていません。メンバー関数を呼び出したい場合は、クラス名で該当する関数を見つけ、オブジェクトのthisポインタを関数に渡すことができます。たとえば、このようなコードです。 CTest test; test.print() コンパイラは内部で(疑似コード)に変換されます。 CTest test; CTestprint &test ); // CTestのprint関数は、CTest_に変換される。print CTest* コンサート this; したがって、一般関数の呼び出しとはあまり違いません。実際には関数でオブジェクトを見つけるべきです。
上の多くの相続問題を解決するために、c++の中で虚相続の概念を提出しました。虚相続とは、子類の中に親類のコピーを一つだけ残しておきます。上の種類を持って言えば、「親類のコピーがあれば親類のコピーを使います。ない場合はコピーを入れます。」:
3、タイガーを引き継ぐメンバー変数 //opを含む()
2、lionを継承するメンバー変数 //コピーが含まれていますので、もうopは含まれていません。
1、liger自体のメンバー変数
このようにメモリの中にはanimalオブジェクトのコピーが一つしかないので、あいまいな問題が存在しません。
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()。エラーが発生します。ファジーなメンバー変数が提示されます。タイガーとlionの両方には父類アニマルのop()が含まれています。このときのメモリのオンライガーオブジェクトレイアウトは、低いから高いまでは以下のようになります。1、アニマルのメンバー変数2、タイガーを引き継ぐメンバー変数 //opを含む()
3、lionを継承するメンバー変数 / /op()も含まれています
4、liger自体のメンバー変数
PS:オブジェクトのメモリ内のレイアウトは、まず虚関数があれば虚表、虚表は関数ポインタ配列のポインタを指します。そして、メンバー変数です。普通に継承されている場合は、最初に一番根父類のメンバー変数です。次に次父類メンバー変数です。順番に最後に自分のメンバー変数です。メンバー関数は、大域関数としてコンパイルされ、オブジェクト空間には記憶されていません。メンバー関数を呼び出したい場合は、クラス名で該当する関数を見つけ、オブジェクトのthisポインタを関数に渡すことができます。たとえば、このようなコードです。 CTest test; test.print() コンパイラは内部で(疑似コード)に変換されます。 CTest test; CTestprint &test ); // CTestのprint関数は、CTest_に変換される。print CTest* コンサート this; したがって、一般関数の呼び出しとはあまり違いません。実際には関数でオブジェクトを見つけるべきです。
上の多くの相続問題を解決するために、c++の中で虚相続の概念を提出しました。虚相続とは、子類の中に親類のコピーを一つだけ残しておきます。上の種類を持って言えば、「親類のコピーがあれば親類のコピーを使います。ない場合はコピーを入れます。」:
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対象はメモリ内のレイアウトになります。アニマルのメンバー変数3、タイガーを引き継ぐメンバー変数 //opを含む()
2、lionを継承するメンバー変数 //コピーが含まれていますので、もうopは含まれていません。
1、liger自体のメンバー変数
このようにメモリの中にはanimalオブジェクトのコピーが一つしかないので、あいまいな問題が存在しません。