More C++ Idioms/チェック付きdelete(Checked delete)

チェック付きdelete(Checked delete)

編集

意図

編集

delete 式の安全性を向上する。

別名

編集

動機

編集

C++ 標準は 5.3.5/5 において、delete 式によって、不完全なクラス型へのポインタを delete することを認めている。 自明でないデストラクタか、クラス独自の delete 演算子を持つクラスの場合、未定義動作となる。 不完全型が delete されるとき、警告を出すコンパイラもあるが、不幸なことに全てのコンパイラではなく、また、プログラマは警告を無効にしたり無視する場合がある。

解法とサンプルコード

編集

チェック付きdelete(Checked delete)イディオムは、delete 対象の型が不完全型の場合にコンパイラにエラーを出すことを強制する。 下記のコードは boost 中の checked_delete 関数テンプレートの実装である。 型 T が定義されていない場合、例えば、前方宣言しかない場合等に、負の要素数となる配列を宣言することでコンパイラにエラーを出すことを強制する。

template<class T> 
inline void checked_delete(T * x)
{
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete x;
}
template<class T> 
struct checked_deleter : std::unary_function <T *, void>
{
    void operator()(T * x) const
    {
        boost::checked_delete(x);
    }
};

これらの関数テンプレート、クラステンプレートにより、完全型が要求され、さもなくばコンパイルエラーが生じることで、問題を避けられる。 配列に対する delete 演算子でも同様に適用可能である。

注意 std::auto_ptr はチェック付き delete のようなものは全く使っていない。 そのため、不完全型によって std::auto_ptr をインスタンス化し、std::auto_ptr の宣言時点(point of declaration)でテンプレートパラメータの型が不完全である場合には、デストラクタ中で未定義動作を引き起こすかもしれない。

既知の利用

編集

関連するイディオム

編集

References

編集

http://www.boost.org/libs/utility/checked_delete.html