是否可以在不调用析构函数的情况下删除c ++中的对象?

Mik*_*cki 9 c++ destructor memory-management

我有一个对象,里面有一些指针.析构函数调用delete这些指针.但有时我想删除它们,有时我不删除它们.所以我希望能够在调用析构函数的情况下删除对象.这可能吗?

编辑:我意识到这是一个绝对的想法,没有人应该这样做.尽管如此,我想这样做是因为它会使一些内部函数更容易编写.

bam*_*s53 9

delete运营商做两件事情给你传递的对象:

  • 调用适当的析构函数.
  • 调用deallocation函数operator delete.

因此,在不调用析构函数的情况下删除对象意味着您只想调用operator delete该对象:

Foo *f = new Foo;
operator delete(f);
Run Code Online (Sandbox Code Playgroud)

operator delete是一个正常的函数调用,通常的名称查找和重载解析完成.但是,delete运营商有自己的规则来找到正确的operator delete.例如,delete运算符将查找operator delete通常的名称查找和重载分辨率找不到的成员函数.这意味着您需要确保在手动使用时调用正确的功能operator delete.

如你所说,operator delete直接使用是一个糟糕的主意.未能调用析构函数会破坏RAII,从而导致资源泄漏.它甚至可能导致未定义的行为.此外,您还必须承担编写没有RAII的异常安全代码的责任,这非常困难.你几乎可以保证弄错了.

  • `delete f` 实际上是 `f->~Foo(); operator delete(f);` (就像 `new Foo` 实际上是 `new (operator new(sizeof(Foo))) Foo`)。这些“*不相交的分配/从构造/销毁中释放*”的形式很少见,但当内存的历史不遵循它所持有的对象的历史时就会发生。这通常可以在“std::vector”实现中找到。 (2认同)

ana*_*lyg 8

您可以将指针设置为NULL,然后析构函数不会删除它们.

struct WithPointers
{
    int* ptr1;
    int* ptr2;

    WithPointers(): ptr1(NULL), ptr2(NULL) {}

    ~WithPointers()
    {
        delete ptr1;
        delete ptr2;
    }
}

...
WithPointers* object1 = new WithPointers;
WithPointers* object2 = new WithPointers;
object1->ptr1 = new int(11);
object1->ptr2 = new int(12);
object2->ptr1 = new int(999);
object2->ptr2 = new int(22);
...
int* pointer_to_999 = object2->ptr1;
object2->ptr1 = NULL;
delete object1;
delete object2; // the number 999 is not deleted now!
// Work with the number 999
delete pointer_to_999; // please remember to delete it at the end!
Run Code Online (Sandbox Code Playgroud)