跳轉到內容

更多 C++ 慣用法/Checked delete

來自 Wikibooks,開放書籍,開放世界

Checked delete

[編輯 | 編輯原始碼]

提高delete表示式的安全性。

也稱為

[編輯 | 編輯原始碼]

動機和示例程式碼

[編輯 | 編輯原始碼]

C++ 標準允許在 5.3.5/5 中,使用 delete-expression 刪除指向不完整類型別的指標。當類具有非平凡解構函式或類特定的 operator delete 時,行為是未定義的。一些編譯器在刪除不完整型別時會發出警告,但不幸的是,並非所有編譯器都會這樣做,並且程式設計師有時會忽略或停用警告。

在以下示例中,main.cpp 可以看到 Object 的定義。但是,main() 呼叫在 deleter.cpp 中定義的 delete_object(),它沒有看到 Object 的定義,而只是向前宣告它。對像這樣部分定義的型別呼叫 delete 是未定義的行為,一些編譯器不會標記它。

////////////////////
// File: deleter.hpp
////////////////////
// Declares but does not define Object.
struct Object;
void delete_object(Object* p);

////////////////////
// File: deleter.cpp
////////////////////
#include "deleter.hpp"

// Deletes an Object without knowing its definition.
void delete_object(Object* p)
{
  delete p;
}

////////////////////
// File: object.hpp
////////////////////
struct Object
{
  // This user-defined destructor won't be called when delete is
  // called on a partially-defined (i.e., predeclared) Object.
  ~Object() {
     // ...
  }
};

////////////////////
// File: main.cpp
////////////////////
#include "deleter.hpp"
#include "object.hpp"

int main() {
  Object* p = new Object;
  delete_object(p);
}

解決方案和示例程式碼

[編輯 | 編輯原始碼]

Checked Delete 慣用法依賴於對函式模板的呼叫來刪除記憶體,該模板對於已宣告但未定義的型別將失敗,而不是對 delete 的呼叫。

以下是 Boost 效用庫中的函式模板 boost::checked_delete 的實現。它透過對引數化型別 T 呼叫 sizeof 運算子來強制編譯錯誤。如果 T 已宣告但未定義,sizeof(T) 將生成編譯錯誤或返回零,具體取決於編譯器。如果 sizeof(T) 返回零,checked_delete 透過宣告具有 -1 個元素的陣列來觸發編譯錯誤。陣列名稱是 type_must_be_complete,在這種情況下,它應該出現在錯誤訊息中,有助於解釋錯誤。

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);
    }
};

注意:相同的技術也可以應用於陣列刪除運算子。

警告:std::auto_ptr 不使用任何等效於 checked delete 的東西。因此,如果在宣告 auto_ptr 時,模板引數型別未完全定義,則使用不完整型別例項化 auto_ptr 可能會導致其解構函式中的未定義行為。

已知用途

[編輯 | 編輯原始碼]
[編輯 | 編輯原始碼]

參考資料

[編輯 | 編輯原始碼]
華夏公益教科書