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

发布于 2024-08-08 21:05:58 字数 331 浏览 2 评论 0原文

在下面的代码中怎么可能允许使用私有析构函数删除对象?我已将实际程序简化为以下示例,但它仍然可以编译并运行。

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

How is that possible that it is allowed to delete object with private destructor in the following code? I've reduced real program to the following sample, but it still compiles and works.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

压抑⊿情绪 2024-08-15 21:05:58

您正在尝试删除不完整类类型的对象。 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;
}

You are trying to delete object of incomplete class type. C++ Standard says that you'll get undefined behavior in this case (5.3.5/5):

If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined.

To detect such cases you could use 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;
}
老娘不死你永远是小三 2024-08-15 21:05:58

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

因此,严格来说,您的代码无法“工作”。它只是简单地编译并在运行时执行一些未定义的操作。

只是编译器不需要捕获此错误。这样做的原因是,如果您的对象有一个简单的析构函数,那么这可能完全没问题。编译器无法知道该类型最终将具有什么样的析构函数,因此无法确定这是否是错误。

This code causes undefined behavior (UB). It is UB in C++ to delete an object of incomplete type having a non-trivial destructor. And in your code the type SomeClass is incomplete at the point of delete, and it has a non-trivial destructor. Compilers usually issue a warning about this, since in C++ formally this is not a constraint violation.

So, strictly speaking, your code doesn't "work". It simply compiles and does something undefined when run.

The compiler is just not required to catch this error. The reason for this is that this could be perfectly fine if your object has a trivial destructor. The compiler has no way of knowing what kind of destructor this type will eventually have, so it can't say for sure whether this is an error or not.

梦过后 2024-08-15 21:05:58

因为调用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.

Because SomeClass type is not completely declared when invoking operator delete.

Deleting such a pointer is undefined behavior, but in practice most compilers would just free the memory (if the pointer was non-NULL) and not call the destructor.

For example, g++ will give you a warning about this issue:

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文