基本クラスのコンストラクター内で-仮想メソッドを呼び出すとき-派生ではなく、基本メソッドが呼び出されることを知っています-コンストラクター内での仮想関数の呼び出しを参照してください。
私の質問はこのトピックに関連しています。派生クラスのコンストラクターで仮想メソッドを呼び出すとどうなるのだろうと思っていましたが、基本部分を構築する前です。基本クラスのコンストラクター引数を評価するために仮想メソッドを呼び出すことを意味します。コードを参照してください:
class Base {
public:
Base(const char* name) : name(name) {
cout << "Base():" << name << endl;
}
virtual const char* getName() {
cout << "Base::getName()" << endl;
return "Base";
}
protected:
const char* name;
};
class Derived : public Base {
public:
Derived() : Base(getName()) {
cout << "Derived():" << name << endl;
}
virtual const char* getName() {
cout << "Derived::getName()" << endl;
return "Derived";
}
};
int main() {
Derived d;
}
コンパイラ g++ (4.3.x-4.5x バージョン) の出力は次のとおりです。
Derived::getName()
Base():Derived
Derived():Derived
しかし、私は期待します:
Base::getName()
Base():Base
Derived():Base
これは間違っているようには見えませんが、次の例を考えてみましょうsegmentation fault
。
class Derived : public Base {
public:
Derived() : Base(getName()), name(new string("Derived")) {
cout << "Derived():" << Base::name << endl;
}
virtual const char* getName() {
cout << "Derived::getName()" << endl;
return name->c_str();
}
private:
string* name;
};
答えてください: これは正しい g++ の動作ですか? それについてどのC++標準が述べていますか? 多分それは未定義の動作ですか?
[UPDATE1] Robert と Oli の回答を考慮して、最初の例を変更しました。次に、 getName() が「仮想」と呼ばれ、セグメンテーション違反が発生します。この部分についても私の質問に答えてください。
const char* virtualGetName(Base* basePtr)
{
return basePtr->getName();
}
class Derived : public Base {
public:
Derived() : Base(virtualGetName(this)) {
cout << "Derived():" << Base::name << endl;
}
virtual const char* getName() {
cout << "Derived::getName()" << endl;
return "Derived";
}
};