CVFCD
C++ 検査 への移動
説明
派生クラスでのオーバーライドがまだ行われていないため、コンストラクタでは仮想呼び出しメカニズムが無効になっています。 オブジェクトは、"派生クラスより先に基底クラス" の方式で、基底クラスから順に作成されます。 そのため、コンストラクタやデストラクタで仮想関数を使用しないことをお勧めします。
オブジェクトの破棄は "基底クラスより先に派生クラス" の方式で行われるため、デストラクタ内の仮想関数はコンストラクタの場合と同じように動作します。 ローカルの定義のみ使用し、オーバーライド関数を呼び出さないようにして、オブジェクトの派生クラスの部分 (既に破棄されたもの) に触れないようにする必要があります。
誤った例
#include <iostream>
#include <string>
using namespace std;
class B {
public:
B(const string& ss) { cout << "B constructor\n"; f(ss); }
virtual void f(const string&) { cout << "B::f\n";}
};
class D : public B {
public:
D(const string& ss) :B(ss) { cout << "D constructor\n";}
void f(const string& ss) { cout << "D::f\n"; s = ss; }
private:
string s;
};
int main() {
D d("Hello");
}
このプログラムはコンパイルが成功し、実行すると以下の結果が出力されます。
B constructor
B::f
D constructor