2009-03-10 31 views
136

を書くのは、それが間違っている:抽象基本クラスの純粋仮想デストラクタ

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

少なくともMSVCでコンパイルすると...実行時にクラッシュするのですか?

+7

これはコンパイルすることができるが、しかしリンクしていますか? –

答えて

182

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

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

inline A::~A() { } 

で十分です。

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

編集:より多くの適合を宣言を固定し、http://www.comeaucomputing.com/tryitout/

+0

したがって、 "〜0"を除いてvirtual〜A(){}と宣言する必要があります。あなたが実装を提供するなら、それは純粋な仮想ではありません – jalf

+15

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

+65

実際には純粋な仮想関数を実装することは合法です。デフォルト実装を提供するが、サブクラスが明示的にそれを呼び出すようにするのに非常に便利です。 – jmucchiello

45

プライベートデストラクタでコンパイルされた:あなたは、派生クラスのオブジェクトを作成するとき、彼らはあなたにエラーを与える - ないそう。診断が表示されることがあります。

12.4デストラクタ

6デストラクタは、仮想(10.3)又は(10.4)純粋仮想宣言することができます。そのクラスの任意のオブジェクトまたは派生クラスがプログラム内に作成された場合、デストラクタを定義しなければならない。

純粋な仮想デストラクタを持つクラスは抽象クラスです。ウェル 注:

10.4抽象クラス

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

[:関数宣言は、純粋な指定子と定義末端 ノート両方提供することはできない]ドラフトから直接取ら

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

+1。私はHerb Sutterもこれに関するいくつかの良い情報を持っていると思う:http://www.gotw.ca/gotw/031.htm。興味深いのは、任意の純粋仮想関数が、デストラクタだけでなく、実装を提供できることです。 –

+6

はい、それはあなたの面接官を変えるために面接でやることです) – dirkgently

+1

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

関連する問題