4
class A
{
public:
    ...
    virtual bool Function(..) const {...}
}

class B : public A
{
public:
    ...
    virtual bool Function(..) const {...}
}

class OtherClass
{
public:
    OtherClass(A& a)
    {
        m_bool = a.Function(..);
    }
private:
    bool m_bool;
}

クラス OtherClass を構築する前に、クラス A またはクラス B が完全に初期化されているとします。

質問>OtherClassのコンストラクタでの仮想関数の呼び出しに問題はありますか?

4

3 に答える 3

5

いいえ、なぜ問題があるのですか?Aのコンストラクターに(参照を介して)渡されたインスタンスOtherClassはすでに完全に初期化されているため、その上の仮想関数は期待どおりに機能します。

聞いた警告は、コンストラクター内で作成しているオブジェクトの仮想関数を呼び出すことに関するものです。この場合、仮想ディスパッチは無効になります。つまり、各基本クラスのコンストラクターでは、呼び出される仮想関数バージョンは、コンストラクターが実行されている基本クラスの1つです。

基本クラスのコンストラクター内では、オブジェクトはまだ最終的な型にはなっていないという考え方です。つまり、ある基本クラスから継承するオブジェクトを作成している間、そのオブジェクトは「基本」型として開始され、各派生クラスコンストラクターが実行されると派生型に遷移します。これは、さまざまなコンストラクターが実行時に表示される仮想関数のバージョンに反映されます。

あなたはそれについてもっと詳細にここで読むことができます。

繰り返しになりますが、コンストラクターに渡されるオブジェクトはすでに完全に構​​築されているため、これは影響を与えません。したがって、それらの「決定的な型」(したがって対応する仮想関数のセット)はすでに完全に確立されています。

于 2012-12-10T17:42:26.120 に答える
2

関数が定義されていて、純粋仮想関数や抽象基本クラスではない場合、関数呼び出しは問題ないはずです。オブジェクトはa期待どおりに仮想関数を呼び出すので、質問に答えるには、いいえ

于 2012-12-10T17:42:42.653 に答える
0

A/B の仮想関数の呼び出しは、それが OtherClass のコンストラクターから呼び出されたか、他の場所から呼び出されたかとは関係ありません。だから問題ありません。

于 2012-12-10T20:40:13.823 に答える