다음과 같이 코드를 작성했다고 가정해 보자.
struct Object;
void delete_object(Object* p);
#include "deleter.hpp"
void delete_boject(Object* p)
{
delete p;
}
struct Object
{
~Object(){
std::cout<<"delete!"<<"\n";
}
};
#include "deleter.hpp"
#include "object.hpp"
int main(){
Object* p = new Object;
delete_object(p);
}
이렇게 코드를 짜면, Object의 ~Object가 호출되지 않고, Object객체 p가 소멸된다.
따라서 코드를 짜다 보면 이렇게 소멸자가 호출되지 못하는 경우가 발생하며, 오류가 발생할 수 있다.
이를 위한 Idioms가 checked delete이다.
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);
}
};
위 코드는 sizeof를 호출하여 컴파일 오류를 실행하는 구문이다. T가 선언되었지만 정의되지 않은 경우 컴파일 오류를 생성하거나 0을 반환한다.