使用私有析构函数删除对象

big*_*g-z 9 c++ memory-management private-members

如何允许在以下代码中使用私有析构函数删除对象?我已将实际程序缩减为以下示例,但它仍然可以编译并运行.

class SomeClass;

int main(int argc, char *argv[])
{
  SomeClass* boo = 0; // in real program it will be valid pointer
  delete boo; // how it can work?

  return -1;
}

class SomeClass
{
private:
  ~SomeClass() {}; // ! private destructor !
};
Run Code Online (Sandbox Code Playgroud)

Kir*_*sky 15

您正在尝试删除不完整类类型的对象.C++ Standard说在这种情况下你会得到未定义的行为(5.3.5/5):

如果被删除的对象在删除时具有不完整的类类型,并且完整的类具有非平凡的析构函数或释放函数,则行为是未定义的.

要检测此类情况,您可以使用boost::checked_delete:

template<typename T> 
inline void checked_delete( T* p )
{
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete p;
}
Run Code Online (Sandbox Code Playgroud)

  • @Kirill"`struct X {};`是空的,它会在任何兼容的C编译器上导致编译错误(或者更正式地说,"诊断消息").因为,如上所述,C不允许空结构. (2认同)

AnT*_*AnT 7

此代码导致未定义的行为(UB).C++中delete的UB是一个具有非平凡析构函数的不完整类型的对象.并且在你的代码中,类型SomeClass是不完整的delete,它有一个非平凡的析构函数.编译器通常会发出警告,因为在C++中,这不是违反约束的.

因此,严格地说,您的代码不"有效".它只是编译并在运行时执行一些未定义的操作.

编译器不需要捕获此错误.这样做的原因是,如果你的对象有一个简单的析构函数,这可能是完全正常的.编译器无法知道此类型最终会具有哪种析构函数,因此无法确定这是否是错误.