为什么C++默认析构函数不会破坏我的对象?

Osz*_*kar 28 c++ destructor default

C++规范说默认析构函数删除所有非静态成员.然而,我无法实现这一目标.

我有这个:

class N {
public:
    ~N() {
        std::cout << "Destroying object of type N";
    }
};

class M {
public:
    M() {
        n = new N;
    }
//  ~M() { //this should happen by default
//      delete n;
//  }
private:
    N* n;
};
Run Code Online (Sandbox Code Playgroud)

然后这应该打印给定的消息,但它不会:

M* m = new M();
delete m; //this should invoke the default destructor
Run Code Online (Sandbox Code Playgroud)

Fre*_*son 46

是什么让你认为对象n指向应该默认删除?默认的析构函数会破坏指针,而不是它指向的指针.

编辑:我会看看能不能说清楚一点.

如果你有一个本地指针,并且它超出范围,你会期望它指向的对象被销毁吗?

{
    Thing* t = new Thing;

    // do some stuff here

    // no "delete t;"
}
Run Code Online (Sandbox Code Playgroud)

t指针被清理,但Thing它指向的不是.这是一个泄漏.基本上同样的事情发生在你的班上.

  • @Oszkar:规范只需要销毁自动对象......在这种情况下,指针*一旦超出范围就会被销毁.但是如果`some stuff`将指针传递给另一个不超出范围的对象/函数呢?"Thing"还应该被销毁吗? (3认同)
  • 即使您添加了注释掉的位,您也可能需要在实际看到输出之前清除流 (2认同)

P S*_*ved 16

想象一下这样的事情:

class M {
public:
    M() { }
//  ~M() {        // If this happens by default
//      delete n; // then this will delete an arbitrary pointer!
//  }
private:
    N* n;
};
Run Code Online (Sandbox Code Playgroud)

你可以自己使用C++中的指针.没有人会自动删除它们.

默认的析构函数确实会销毁所有成员对象.但是在这种情况下,成员对象本身就是一个指针,而不是指向它的东西.这可能会让你困惑.

但是,如果不使用简单的内置指针,则会使用智能指针,破坏这样的"指针"(实际上是一个类)可能会触发指向对象的破坏.

  • 这就是智能指针存在的原因,因此会有自动销毁. (6认同)

Dav*_*ley 8

默认的析构函数正在销毁指针.如果要删除Nwith M的默认析构函数,请使用智能指针.更改N * n;auto_ptr<N> n;n将被销毁.

编辑:正如评论中所指出的,auto_ptr<>它不是所有用途的最佳智能指针,但它看起来像这里所要求的.它具体代表所有权:M中的N在M的持续时间内不再存在.复制或分配a auto_ptr<>表示所有权的更改,这通常不是您想要的.如果你想从M传递指针,你应该传递一个N *来自n.get().

一个更通用的解决方案是boost::shared_ptr<>,它将采用C++ 0x标准.在任何使用原始指针的地方都可以使用它.它不是最有效的构造,并且在循环引用方面存在问题,但它通常是一种安全的构造.

另一个编辑:要在另一个注释中回答问题,默认析构函数的标准行为是销毁所有数据成员和基类.但是,删除原始指针只会删除指针,而不是它指向的指针.毕竟,实现无法知道这是唯一的指针,还是重要的指针,或类似的东西.智能指针背后的想法是删除智能指针至少会导致删除它指向的内容,这通常是所需的行为.

  • 在使用auto_ptr之前,您应该确保了解正在发生的事情.它的复制和赋值语义可能不是你所期望的. (3认同)

fre*_*low 6

当指向对象似乎属于包含的对象时,是否有任何理由使用指针?只需按值存储对象:

class M
{
    N n;

public:

    M() : n()
    {
    }
};
Run Code Online (Sandbox Code Playgroud)