1.
Secrets of Boost Revealed: Checked Delete
http://www.cplusplus.com/forum/articles/44968/
看boost的smart ptr 的实现时,发现
template<class T> void checked_delete(T* p),查了一下:
当对不完整的类(看不到implementation)进行delete操作时,有可能发生undefined行为。
example:
/* Deleter.hpp */ #include<cstdlib> class A; class B; class C; void func1(A* a); void func2(B* b); void func3(C* c); /* End of Deleter.hpp */ /* Deleter.cpp */ #include "Deleter.hpp" void func1(A* a) { delete a; } void func2(B* b) { delete b; } void func3(C* c) { delete c; } /* End of Deleter.cpp */ /* Classes.hpp */ class A { private: int* x; public: A(void) { x = new int(4); } ~A(void) { delete x; } }; class B { }; class C { public: void operator delete(void* pointer) { free(pointer); } }; /* End of Classes.hpp */ /* Main.cpp */ #include "Deleter.hpp" #include "Classes.hpp" int main(void) { A* a = new A; func1(a); // <-- Undefined Behavior - A has a non-trivial destructor B* b = new B; func2(b); // <-- Legal - B has a trivial destructor and does not overload operator delete C* c = new C; func3(c); // <-- Undefined Behavior - C has an overloaded operator delete return 0; } /* End of Main.cpp */
为解决这个问题,boost实现在编译阶段检测(通过sizeof符):
template<class T> void checked_delete(T* p) { typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; (void) sizeof(type_must_be_complete); delete p; } template<class T> struct checked_deleter { typedef void result_type; typedef T * argument_type; void operator()(T * x) const { boost::checked_delete(x); } }; template<class T> void checked_array_delete(T* p) { typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; (void) sizeof(type_must_be_complete); delete [] p; } template<class T> struct checked_array_deleter { typedef void result_type; typedef T * argument_type; void operator()(T * x) const { boost::checked_array_delete(x); } };