C++ のコンストラクターに関するベスト プラクティスを教えてください。コンストラクターで何をすべきか、何をすべきでないかがよくわかりません。
属性の初期化や親コンストラクタの呼び出しなどにのみ使用すべきでしょうか?それとも、設定データの読み取りや解析、外部ライブラリの設定など、より複雑な機能も組み込むべきでしょうか?
それとも、このために特別な関数を書くべきでしょうか? Resp. init()
/ cleanup()
?
ここでの長所と短所は何ですか?
たとえば、init()
と を使用するときに共有ポインターを削除できることが分かりましたcleanup()
。スタック上にクラス属性としてオブジェクトを作成し、構築済みの状態で後で初期化することができます。
コンストラクターで処理する場合は、実行時にインスタンス化する必要があります。次にポインターが必要です。
どう決めればいいのか本当に分からない。
もしかしたら助けてくれるかもしれませんか?
ベストアンサー1
の最も一般的な間違いコンストラクタでもデストラクタでも実行できるもう 1 つの方法は、ポリモーフィズムを使用することです。ポリモーフィズムはコンストラクタでは機能しないことが多い!
例えば:
class A
{
public:
A(){ doA();}
virtual void doA(){};
}
class B : public A
{
public:
virtual void doA(){ doB();};
void doB(){};
}
void testB()
{
B b; // this WON'T call doB();
}
これは、親クラスAのコンストラクタを実行している間にオブジェクトBがまだ構築されていないためです。したがって、オーバーライドされたバージョンを呼び出すことは不可能です。void doA();
多態性の例 意思 コンストラクタで作業:
class A
{
public:
void callAPolymorphicBehaviour()
{
doOverridenBehaviour();
}
virtual void doOverridenBehaviour()
{
doA();
}
void doA(){}
};
class B : public A
{
public:
B()
{
callAPolymorphicBehaviour();
}
virtual void doOverridenBehaviour()
{
doB()
}
void doB(){}
};
void testB()
{
B b; // this WILL call doB();
}
virtual
この場合の理由は次のとおりです。関数が呼び出された時点でdoOverridenBehaviour()
、オブジェクト b はすでに初期化されています (ただし、まだ構築されていません)。つまり、その仮想テーブルは初期化されており、ポリモーフィズムを実行できます。