0

friend私はそれが継承されていないことを理解しています。クラスがありますParent Person Child。親と人はお互いの友達です。親には次の保護機能があります。

class Person
{
    friend class Parent;
    public:
        Parent * parent;
}

class Parent
{
    friend class Person;
    protected:
        virtual void Answer() = 0;
}

class Child : public Parent
{
    void Answer()
    {
        std::cout << "Child!" << endl;
    }
}

私の質問は、友情が受け継がれていなければ、どうすれば次のことができるのかということです...?(人は親へのポインタを持っています)

Person person;
Child child;
person.parent->Answer();

このChild!の出力がなぜであり、仮想関数にアクセスしようとしたときにランタイムエラーがスローされないのですか?

子の関数がどのように実装されているかについて混乱しており、親の仮想応答関数を呼び出そうとしていると予想されるため、プログラムは実行時にエラーになりません。

4

1 に答える 1

3

あなたはアクセスしていませんChild::Answerが、ここはあなたの友達Parent::Answerだから大丈夫です。ParentこれがChildオブジェクトであるという事実は問題ではありません。ただし、実行時に実際に呼び出されるメソッドは重要です。Parent::Answerisであるためvirtual、 でオーバーライドすると、 aがChild::Answer何であるかを知らない呼び出し元が、 が参照またはポインターを介してアクセスされた場合でも呼び出し続けることになります (実行時に適切な関数を解決する間接レイヤーがあります)。ChildChild::AnswerChildParent

実装する前にこれをコンパイルしChild、後でこのファイルにリンクして、またはとして偽装し.oたインスタンスを渡すこともできます。何かが呼び出されていることを知る機会さえありませんでしたが、それでも正しい実装を「見つける」ことができます。それが動的バインディングの力です。ChildParent&Parent*PersonChild

于 2012-04-18T18:05:23.813 に答える