C++ 是否可以删除c++;没有调用析构函数?

C++ 是否可以删除c++;没有调用析构函数?,c++,memory-management,destructor,C++,Memory Management,Destructor,我有一个物体,里面有一些指针。析构函数对这些指针调用delete。但有时我想删除它们,有时我不想。因此,我希望能够在不调用析构函数的情况下删除该对象。这可能吗 编辑:我意识到这是一个可怕的想法,任何人都不应该这样做。尽管如此,我还是想这样做,因为它将使一些内部函数更易于编写。Eww!是的,这是可能的,不,我不会这么做。让需要变量生存期的对象通过共享指针或其他引用计数对象来控制。更清洁地使用C++而不是破坏它的内部租户… < P>不管你实际上想做什么,代码都有问题。 如果不想删除子对象,只需使用在

我有一个物体,里面有一些指针。析构函数对这些指针调用
delete
。但有时我想删除它们,有时我不想。因此,我希望能够在不调用析构函数的情况下删除该对象。这可能吗


编辑:我意识到这是一个可怕的想法,任何人都不应该这样做。尽管如此,我还是想这样做,因为它将使一些内部函数更易于编写。

Eww!是的,这是可能的,不,我不会这么做。让需要变量生存期的对象通过共享指针或其他引用计数对象来控制。更清洁地使用C++而不是破坏它的内部租户…

< P>不管你实际上想做什么,代码都有问题。 如果不想删除子对象,只需使用在删除对象之前设置的布尔标志,析构函数将考虑该标志


但老实说,您应该使用智能指针而不是裸指针(在您的情况下,看起来共享指针就是您所需要的)。

正如其他人所建议的,解决此问题的正确方法不是不调用析构函数[您只需向对象添加类似于
std::string
std::vector
的内容,然后突然出现内存泄漏]。正确的方法是要么不让对象拥有这些其他对象(例如,在删除对象之前/之后分别删除它们),或具有对象知道是否删除指针的方法。

您可以将指针设置为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!

编写一个可以在调用析构函数之前调用的方法。该方法将翻转一个布尔成员。调用析构函数时,它将检查该布尔成员并销毁指针(如果为true),如果为false则保留它


我不建议这样做。最好不要让类负责删除指针。

是的,这是可能的。
std::vector
这样做,因为它为对象分配缓冲区空间,然后有条件地(就地)构造它们并销毁它们,独立于对象生命周期管理内存

在C++11中,我会使用您的类型的
并集
,以及一个小类型(带有琐碎的构造函数/析构函数)来指示可以适合您的类型的内存位置,但不必在其中包含该类型。除此之外,您必须跟踪对象是否实际存在。创建项包括使用placement
new
和destr>oying它包括手动调用析构函数

union
对象的缓冲区(无论是N个对象还是1个对象)将完全独立管理。
union
的默认构造函数要么不构造任何内容,要么构造普通类型(在这种情况下,您可能希望销毁该普通类型)


然而,问题的真正答案很可能是“不要那样做”。如果你这样做,你将指针封装在一个
类中,该类的唯一任务是处理上述混乱。这种类型的类(其任务是管理指针的生存期和指针类属性)称为“智能指针”.

删除操作符对传递给它的对象执行两项操作:

  • 调用相应的析构函数
  • 调用解除分配函数,
    操作员删除
因此,在不调用析构函数的情况下删除对象意味着只需对对象调用
操作符delete

Foo *f = new Foo;
operator delete(f);
operator delete
是一个正常的函数调用,通常会进行名称查找和重载解析。但是
delete
操作符有自己的规则来查找正确的
operator delete
。例如
delete
操作符将查找通常使用的成员
operator delete
函数找不到名称查找和重载解析。这意味着您需要确保在手动使用
operator delete
时调用了正确的函数


正如您所说,直接使用
操作符delete
是一个糟糕的想法。未能调用析构函数会破坏RAII,导致资源泄漏。它甚至可能导致未定义的行为。此外,您还必须承担在没有RAII的情况下编写异常安全代码的责任,这非常困难。您几乎可以保证获得它ong.

我知道这是正确的方法,但出于各种原因,我想用我自己的方法来做。这不是公开的功能,而是内部使用的使一些功能更简单的东西。我建议你不要去那里。谁知道,当将来有人走进你的代码,并在你的代码中夹杂一些东西时d boom.或者一个新的编译器版本,等等。违反规则会使调试变得非常困难,因为解决方案不是查看代码时想到的前20件事。它可能会使一些内部函数“更容易编写”(有争议)但这肯定不会使它们更安全或更容易维护。任何人在你之后看这段代码都会认为你疯了。@MikeIzbicki:当它坏了的时候,说一些更简单的东西有意义吗?这是给学生代码评分的测试工具(我是助教)。我真的不想手动编辑他们所有的100个类,因为这个黑客可以正常工作并且可以自动完成。所以问题是如何使动态分配的对象以一种不需要显式调用
delete
/
free
?@LihO是。或者,调用
delete
/
fr的方式被释放ee
而不调用析构函数。好吧,只需将这些内部指针设置为
nullptr
,然后
delete
将它们删除将是不可操作的。
delete
调用