13

in 基本クラスにはpure virtual destructor定義が必要です。そうしないと、コンパイラはリンク時に派生クラス デストラクタから基本クラス デストラクタへの呼び出しを生成し、リンク エラーが発生します。

以下のように、基本クラス内で純粋仮想デストラクタを定義しようとしました。

class base
{
   public:
      base()
      {
         cout << "constructor in base class\n";
      }

      virtual ~base()=0
      {}
};

これにより、コンパイルエラーが発生しました:

エラー: 関数定義の純粋指定子

次に、以下のように基本クラスの外で関数を定義しようとしました:

class base
{
   public:
      base()
      {
         cout << "constructor in base class\n";
      }

      virtual ~base()=0;
};

base::~base()
{

}

これにより、コンパイル エラーが解消され、私の理解どおりに動作します。

しかし、私の質問は、基本クラスの外部で純粋仮想デストラクタを定義すると、コンパイル エラーがどのように削除されるのでしょうか?

4

5 に答える 5

11

2番目の例は正しいです。

他の多くの回答は、デフォルトの実装で純粋仮想関数を持つことは違法であると想定していますが、それは正しくありません。

純粋な仮想デストラクタの場合、定義が必要です ( xmoex 回答のリンクを参照)。

それは真実だ:

§10.4/2 関数宣言は、純粋指定子と定義の両方を提供することはできません

ただし、お気づきのように、宣言の外で定義を提供することが可能です。

于 2011-11-19T14:21:22.077 に答える
7

私はこのページを見ました:

http://www.gotw.ca/gotw/031.htm

そして、私の理解では、すべての派生クラスが基本クラスのデストラクタを呼び出さなければならないため、純粋な仮想デストラクタには (空のものであっても)定義が必要です。

于 2011-11-19T14:20:52.490 に答える
5

次のように書くのは無効な構文です。

virtual ~base()=0
{}

純粋仮想メンバー関数の実装を提供する場合は、クラスの外で行う必要があります。純粋仮想関数はとにかく呼び出されるべきではないため、ほとんどの場合、これを行うべきではありません。ただし、純粋仮想関数の実装を定義することは可能です。

実際、純粋仮想デストラクタには実装が必要です。これは、特定のクラスのデストラクタが純粋仮想であるかどうかに関係なく、オブジェクトの破棄時にすべての基本クラスのデストラクタが呼び出されるためです。

したがって、派生クラスのいずれかのインスタンスを作成すると、baseある時点で、そのオブジェクトが属するすべてのクラスのデストラクタがbase::~base()デストラクタを含めて呼び出されます。定義しないと、リンカは必要なシンボルを見つけられず、文句を言います。

于 2011-11-19T14:20:02.317 に答える
3

デストラクタは、それが純粋な仮想であっても、それが定義されているクラスを有用にするために実装が必要な唯一のメソッドです。したがって、@ Kirilの答えとは対照的に、純粋仮想関数には実装があると言えます

ややオフトピック:

struct base {
    virtual void func() = 0;
};

void base::func() { /* default implementation */ }

class derived : public base{
    void func() { base::func(); } // have to explicitly call default implementation.
};
于 2011-11-19T14:22:05.017 に答える
1

純粋仮想メソッドは実装を持つことができますが、基本クラスを抽象化し、派生クラスがそれらのメソッドを上書きするように強制します。

基本クラスにポインター メンバーがあるとします。デストラクタでそれを削除したいだけでなく、クラスを抽象化したいので、純粋な仮想デストラクタに実装します。

これは実装の詳細です。デストラクタが実装されているという事実は、外部からは見えないようにする必要があります。

于 2011-11-19T14:20:29.683 に答える