C ++の純粋な仮想デストラクタ


回答:


218

はい。また、デストラクタを実装する必要があります。

class A {
public:
    virtual ~A() = 0;
};

inline A::~A() { }

十分なはずです。

そして、これは反対票を投じたので、私は明確にする必要があります:Aから何かを派生させて、それを削除または破棄しようとすると、A最終的にのデストラクタが呼び出されます。純粋で実装がないため、未定義の動作が発生します。人気のあるプラットフォームの1つでは、purecallハンドラーを呼び出してクラッシュします。

編集:http://www.comeaucomputing.com/tryitout/でコンパイルされた、より準拠するように宣言を修正


16
ええと、そうです。純粋とは、派生クラスも実装を提供する必要があることを意味します。
MSN

72
純粋な仮想関数の実装は実際には合法です。デフォルトの実装を提供するが、サブクラスがそれを明示的に呼び出すように強制するのに非常に役立ちます。
jmucchiello 2009年

6
MSNとヘッダーにその定義がある場合は、ODR(1つの定義ルール)に違反しないように、その前に「インライン」を置く必要があります
Johannes Schaub-litb

2
すべてのオブジェクトにデフォルトのデストラクタがあると思ったので、なぜA ::〜A()を明示的に定義する必要があるのですか?あらゆるタイプの継承と同様に、デストラクターのチェーンは常に呼び出され、基本クラスのデストラクターは常に定義される必要はありません。
jeffD

11
より良い方法は、デストラクタを宣言すると、自動的に実装されないことです。
MSN

49

プライベートデストラクタ:派生クラスのオブジェクトを作成すると、エラーが発生します。ただし、診断が表示される場合があります。

12.4デストラクタ

6デストラクタは、仮想(10.3)または純粋仮想(10.4)として宣言できます。そのクラスのオブジェクトまたは派生クラスがプログラムで作成された場合、デストラクタが定義されます。

純粋な仮想デストラクタを持つクラスは、抽象クラスです。よく注意してください:

10.4抽象クラス

2純粋仮想関数は、修飾ID構文(5.1)で呼び出された場合、または(12.4)で呼び出された場合にのみ定義する必要があります。

[ :関数宣言では、純粋指定子と定義の両方を提供することはできません—エンドノート]

ドラフトから直接引用:

struct C {
   virtual void f() = 0 { }; // ill-formed
};

14
+1。Herb Sutterにもこれに関する良い情報があると思います:gotw.ca/gotw/031.htm。純粋な仮想関数には、デストラクタだけでなく、実装が用意されている場合があることに注意してください。
フレッドラーソン、

6
はい、それはあなたの面接官を
驚か

1
私の経験では、実際にはそれほど珍しいことではありません。

@ニールバターワース:どれ?
2009年

@Dirk-「任意の機能」シナリオ。いくつかの一般的な動作を実装するために使用されることを見つけることは珍しいことではありません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.