2012-04-23 4 views
14
// Destructor. If there is a C object, delete it. 
// We don't need to test ptr_ == NULL because C++ does that for us 

    ~scoped_ptr() { 
     enum { type_must_be_complete = sizeof(C) }; 
     delete ptr_; 
    } 

注:Cは、テンプレートパラメータであるデストラクタでは、この列挙型は何ですか?

私たちはNULLポインタを削除カント知って、例外が発生します。 この場合、列挙型定義はそれを防ぐために何かをしているに違いありません。 プロダクションでは、NULLポインターがあるため単純なプログラムを終了したくない場合がありますが、ポインターがヌルの場合は別のシナリオを見たい場合があります。 そして、このコードは、ほぼすべての場所で実稼働環境で使用されていますか?

ありがとうございます。

+7

我々は、そうすることを完全に有効であるNULLポインタを削除することができます。 –

+0

私の問題はポインタの二重削除と混同されていたと思います。コンパイラーによって二重削除が検出された場合、常に例外が発生します。ですから、ヌルポインタの削除とダブル削除の違いは何ですか? – maress

+2

@maress:何度でもヌルポインタを削除することができます(実際には削除しようとすると、ランタイムはヌルポインタを検出して何もしません)。 – rjnilsson

答えて

17

これは効果的に削除のための静的なアサーションです。実装は、前方宣言ではなく、変数を削除する前に宣言が表示されている型を扱っているかどうかを知りたいとします。

あなたはそれ不完全型のサイズ要求したときにエラーが出力されますあなたのコンパイラ:

struct S; 
enum { Size = sizeof(S) }; 

更新あなたのコンパイラとマシューM.​​はあなたを教えてくれるよう

からdelete -ing不完全な型は未定義です。

+1

'sizeof(* ptr_)'を使わないのはなぜですか? – sharptooth

+2

@sharptooth:私は 'C'がより明確であると主張したいと思います。また、タイプする方が速いです:) –

+5

@Justin:不完全な型へのポインタを' delete'しようとすると**未定義の振る舞い* *、これが診断の価値がある理由です。 Boostも同じ効果を持つ 'checked_delete'を持っていますが、再利用できるかもしれませんが、おそらく単純なので、特定のインクルードを保証するとは思えませんでした。 –

0

ブーストchecked_deleterが良さそうです:

template<class T> struct checked_deleter 
{ 
    typedef void result_type; 
    typedef T * argument_type; 
    void operator()(T * p) const; 
}; 

Tは未定義である一方で、いくつかのコンパイラは0を返すことがありますので、その場合には

enum { type_must_be_complete = sizeof(T) }; 

は有効な静的アサートですが、checked_deleterは失敗します。

http://www.boost.org/doc/libs/1_59_0/libs/core/doc/html/core/checked_delete.html#core.checked_delete.checked_deleter

関連する問題