3

Scott Meyers の『Effective C++ 』を読んでいて、継承に関するセクションにいます。彼は言った

純粋仮想関数は、インターフェイスの継承のみを指定します。

単純な (不純な) 仮想関数は、インターフェイスの継承と既定の実装の継承を指定します。

ここで、次の 2 つのクラスを考えます。

struct A {
    virtual void foo() = 0;
};

void A::foo(){ std::cout << "Default foo" << std::endl; }

struct B : A{
    virtual void foo(){ A::foo(); std::cout << "Derived foo" << std::endl; }
};

例で行ったように、純粋な仮想関数のデフォルトの実装を提供し、 を介して呼び出すことができますqualified-function-call-expression。不純な仮想関数についてもほぼ同じことができます

struct A {
    virtual void foo(); //No longer pure virtual
};

void A::foo(){ std::cout << "Default foo" << std::endl; }

struct B : A{
    virtual void foo(){ A::foo(); std::cout << "Derived foo" << std::endl; }
};

次のように不純な仮想関数を定義しない場合:

struct A {
    virtual void foo();
};



struct B : A{
    virtual void foo(){ std::cout << "Derived foo" << std::endl; }
};

それは完全にうまくいくでしょう。

デモ

では、純粋仮想関数の唯一の目的は、クラスを抽象化する (インスタンス化できない) ことですか?

4

1 に答える 1

7

純粋仮想関数は、基本クラスをインスタンス化できないようにするだけでなく、すべての派生クラスに対応する仮想関数を実装するように強制します。基本関数を純粋仮想にしない場合、派生クラスはそれを実装しないことを選択する可能性があります。Scott Meyers が指摘するように、派生インスタンスから使用する限り、純粋仮想関数の定義は問題なく、デフォルトとして使用できる実装を提供します。

あなたのデモはあなたが思うようには動かないことに注意してください。ポリモーフィズムを使用するときに一般的に考えられていることを行うと、

A* p = new B; // or, std::unique_ptr<A> p = make_unique<B>();
p->foo();

次に、厄介なリンカ エラーが発生します。

アーキテクチャ x86_64 の未定義のシンボル:

「A の typeinfo」、参照先: ccoVYpAI.o の B の typeinfo

于 2015-12-03T04:22:21.763 に答える