阻止析构函数被调用

6

我有一个类,在其中我重载了new和delete函数(它们从内存池中获取和返回内存)。让我困扰的是,即使我已经在这个类上进行了重载,它的析构函数仍然在delete被重载的函数调用之前被调用。我该如何阻止这种情况发生?

class Message
{
    ~Message() { ... }

    void* operator new(std::size_t sz) { ... }
    void operator delete(void* ptr) { ... }
};

编辑:

我是否正确地认为类的成员将被销毁,但析构函数不会释放内存;delete函数负责这个责任,因此我可以阻止内存被释放?

结果:我现在明白了内存的分配/释放和构造/析构是两个不同的事情。现在我有了空的析构函数和重载的new/delete。


3
如果你不需要对某个类进行任何操作,可以将析构函数留空。就这个方面而言,C++非常逻辑严密,我不知道为什么会让人感到沮丧。 - Gene Bushuyev
5个回答

6
销毁和释放内存是两个不同的概念,它们应该互不干扰。如果您的类实例是在堆栈上创建的,那么您会怎么处理这些实例?难道不清理它们的资源吗?这样做将会破坏一个非常有用的 RAII概念。

4

我认为你无法阻止析构函数的调用,也不确定为什么你想这样做。在释放内存之前必须销毁对象 - 如果超类分配了一些资源,则其析构函数必须在对象的内存被释放之前释放它们。

编辑后:是的,析构函数清理任何它们分配的内容,但不会释放对象的内存。你正在编写的delete方法会处理这个。

顺便说一下,很好的名字。 :-)


3

如果你关心 (a) 从特定的内存池中获取内存和 (b) 控制析构函数何时被调用,一种选择是使用 placement new

void* raw = allocate(sizeof(Foo));  // line 1
Foo* p = new(raw) Foo();            // line 2

p->~Foo();   // explicitely call destructor

(代码取自上面链接的C++ FAQ)

(从上面的链接中获取的代码)


0
回答你的问题,无论你是否重载new/delete,构造函数和析构函数都会被调用。
回答一个你没有问到的问题,使用内存池与对象一起使用是否是一个好的解决方案,答案通常是“不是”。你需要的是你的类能够使用一个分配器类来处理内存池。这样做能够提供更大的灵活性,而且你通常不只有一个类需要放入内存池中,因此你不希望所有的new/delete函数都被重载。另外,通常有多种分配方案(因此也有多个分配器),但你只需重载一次new/delete即可。

回答你的问题:如何防止在C++中调用析构函数?这只能通过使用放置new进行分配来实现,在这种情况下,您(作为程序员)必须承担手动调用析构函数的责任(就像Doug所说的:p->~Foo::Foo();)。这是语言中唯一需要程序员手动调用析构函数的情况。 - Viren

0

七年后,现在回过头来看,也许轻松显得聪明,但还是让我写下这些。

标准C++(17/20)非常注重值语义驱动的语言,正如其创造者所说的:“新语言”。

所以,请优先考虑使用值(必要时使用引用),并且只有在真正需要时才使用“智能”指针。 最重要的是,忘记重载new和/或delete。你知道的,老套路 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接