サンプルコード
#include <iostream>
using namespace std;
class MyClass {
public:
virtual ~MyClass(); // 仮想デストラクタ
public:
virtual void Say() = 0;
};
class MySubClass :
public MyClass
{
public:
virtual void Say();
};
MyClass::~MyClass() {
// 派生クラスのデストラクタ → 基底クラスのデストラクタ
// https://www.qoosky.io/techs/3fef7fa668
// のため、抽象クラス (=0) であってもこれを省略できません。
}
void MySubClass::Say() {
cout << "MySubClass::Say" << endl;
}
MySubClass CreateMySubClassCopied() {
// コピーコンストラクタ: https://www.qoosky.io/techs/a8ffeeeee6
// でもよいですが、返り値がMySubClassに限定されてしまいます。非推奨。
MySubClass obj;
return obj;
}
MyClass* CreateMySubClass() {
// C++のFactoryMethodで利用します。Javaはこちら: https://www.qoosky.io/techs/1298bf095b
return new MySubClass(); // アップキャストしてポインタで返すのが上等手段です。推奨。
}
int main() {
MySubClass objCopied = CreateMySubClassCopied();
objCopied.Say();
MyClass* obj = CreateMySubClass();
obj->Say();
(*obj).Say(); // 不恰好ですがこうも書けますね (復習)
delete obj; // 仮想デストラクタのおかげで、アップキャストしていても
// 派生クラスのデストラクタが実行されます。
// 継承関係が発生する場合、デストラクタは必ず仮想関数にしましょう。
// (いつでも仮想関数にしておいても実害はないためそうしましょう)
// 配列形式で new することもできます。
// ただし、コンストラクタの引数は指定できません。
MyClass* objs = new MySubClass[2];
objs[0].Say();
delete[] objs;
return 0;
}