使用私有析构函数删除对象
-
05-07-2019 - |
题
如何允许在以下代码中使用私有析构函数删除对象?我已将实际程序缩减为以下示例,但它仍然可以编译并运行。
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 !
};
解决方案
您正在尝试删除不完整类类型的对象。 C ++标准表示在这种情况下你会得到未定义的行为(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;
}
其他提示
此代码导致未定义的行为(UB)。 C ++中的UB是 delete
一个具有非平凡析构函数的不完整类型的对象。在你的代码中, someClass
类型在 delete
处是不完整的,并且它有一个非平凡的析构函数。编译器通常会发出警告,因为在C ++中,这不是违反约束的行为。
因此,严格来说,您的代码并未“正常工作”。它只是编译并在运行时执行 undefined 。
编译器不需要捕获此错误。这样做的原因是,如果你的对象有一个琐碎的析构函数,这可能是完全正常的。编译器无法知道此类型最终会具有哪种析构函数,因此无法确定这是否是错误。
因为在调用 operator delete
时没有完全声明 SomeClass
类型。
删除这样的指针是未定义的行为,但实际上大多数编译器只是释放内存(如果指针是非NULL)而不是调用析构函数。
例如,g ++会给出关于此问题的警告:
foo.cpp: In function 'int main(int, char**)':
foo.cpp:6: warning: possible problem detected in invocation of delete operator:
foo.cpp:5: warning: 'boo' has incomplete type
foo.cpp:1: warning: forward declaration of 'struct SomeClass'
foo.cpp:6: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
不隶属于 StackOverflow