たそうきんぞく
4646 ワード
マルチフェーズコンストレイントの例
複数属性の派生クラスのサイズは?
=>上記の場合、LIgerクラスのサイズは次のとおりです.
Lionのクラス(8+8)+Tigerのクラス(8+8)+Liger(8)
:40バイトを出力します.
Lion*L=new Liger()の場合,LionクラスのvTableのみがLigerのspeakを指す.
反対に
Tiger*L=new Liger()の場合、TigerクラスのvTableのみがLigerのspeakを指す.
Liger*L=new Liger()の場合、TigerとLionクラスの両方のVTableはLigerのspeakを指します.
Diamond Inheritance
:LionとTigerがAnimalクラスを継承する場合.
このとき,Animalクラスのジェネレータは2回呼び出される.
生成者呼び出しが2回発生することを防止するためにvirtual inheritanceを用いる
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Animal
{
public :
Animal()
{
cout << "Animal constructor" << endl;
}
virtual ~Animal()
{
cout << "Animal destructor " << endl;
}
};
class Lion : public Animal
{
public :
Lion()
{
cout << "lion constructor" << endl;
}
virtual ~Lion()
{
cout << "lion destructor" << endl;
}
virtual void speak()
{
cout << "Lion! " << endl;
}
private :
double lionData;
};
class Tiger : public Animal
{
public:
Tiger()
{
cout << "Tiger constructor" << endl;
}
virtual ~Tiger()
{
cout << "Tiger destructor" << endl;
}
virtual void speak()
{
cout << "Tiger! " << endl;
}
private:
double TigerData;
};
class Liger : public Lion, public Tiger
{
public:
Liger()
{
cout << "Liger constructor" << endl;
}
~Liger()
{
cout << "Liger destructor" << endl;
}
void speak()
{
cout << "Liger! " << endl;
}
private:
double LigerData;
};
int main(void)
{
Liger L;
}
->virtualは、Animalの作成者と消滅者を一度だけ呼び出すことを保証します.
最終ソースコード
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Animal
{
public :
Animal()
{
cout << "Animal constructor" << endl;
}
virtual ~Animal()
{
cout << "Animal destructor " << endl;
}
};
class Lion : virtual public Animal
{
public :
Lion()
{
cout << "lion constructor" << endl;
}
virtual ~Lion()
{
cout << "lion destructor" << endl;
}
virtual void speak()
{
cout << "Lion! " << endl;
}
private :
double lionData;
};
class Tiger : virtual public Animal
{
public:
Tiger()
{
cout << "Tiger constructor" << endl;
}
virtual ~Tiger()
{
cout << "Tiger destructor" << endl;
}
virtual void speak()
{
cout << "Tiger! " << endl;
}
private:
double TigerData;
};
class Liger : public Lion, public Tiger
{
public:
Liger()
{
cout << "Liger constructor" << endl;
}
~Liger()
{
cout << "Liger destructor" << endl;
}
//void speak()
//{
// cout << "Liger! " << endl;
//}
private:
double LigerData;
};
int main(void)
{
Liger L;
L.speak(); // 모호성을 발생함.
}
=>LigerのSpeak関数を再定義すると,あいまいな問題はない.Reference
この問題について(たそうきんぞく), 我々は、より多くの情報をここで見つけました https://velog.io/@kwt0124/다중상속テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol