0

如果我在不使用诸如“Object s(someval)”之类的 new 关键字的情况下创建了一个对象,但是该对象构造函数使用了 new,那么当该对象超出范围时,是否会为它的新分配调用析构函数?我觉得好像是,但我不确定。

4

5 回答 5

3

让我们给物体起个名字,好吗?

struct A {
    A() b(new B) {}
    B* b;
    C c;
};

A a;

这里调用了a' 的析构函数的析构函数也是如此A::c(被析构时会自动调用a)。

然而,*A::b' 的析构函数没有被调用——实际上,指针对象A::b 本身被正确地释放了,但是因为它是一个原始类型(它是一个指针!)什么都没有发生。然而,指针 *A::b需要通过调用手动销毁(并释放其内存)delete

于 2013-04-06T18:55:09.823 回答
2

当该对象超出范围时,是否会为它的新分配调用析构函数?

这取决于如何Object定义。

如果返回的指针new存储在某个数据成员中Object,该数据成员deleteObject自身的析构函数调用,那么是new的,当s超出范围时,分配的对象也将被销毁。

否则,没有。在丢失对已分配对象的最后一个指针/引用之前,每个调用都new必须与相应的调用匹配delete,否则会发生内存泄漏

由于这样做很容易失败,并且由于也很容易错误地取消引用悬空的指针(即指向生命周期已结束的对象),因此通常最好避免通过原始指针执行手动内存管理,newdelete(或它们的数组对应项)。

当您需要控制对象的生命周期时,总是更喜欢使用 RAII 包装器,例如std::shared_ptr<>orstd::unique_ptr<>除非您真的知道自己在做什么并且不能做其他事情。

于 2013-04-06T18:53:24.363 回答
0

不,delete如果您将该动态分配的指针存储为数据成员,则必须在析构函数中显式使用它。这也引入了三规则(C++ 11 中的五规则),这很麻烦。这就是为什么在可能的情况下应该优先使用堆栈分配的对象。

当需要指针时,请使用 RAII 包装器,例如std::vector动态分配的数组或智能指针,例如std::unique_ptror std::shared_ptr,用于单个动态分配的对象。这些为您和您管理内存,这不是额外的工作。

于 2013-04-06T18:53:19.777 回答
0

不,它不会......您必须delete在您分配的对象的析构函数中定义new. 您使用在堆上创建一个对象new,当您的对象被销毁时,您将丢失对创建内存泄漏的对象的引用。为避免这种情况,您可以使用智能指针,例如shared_ptr.

于 2013-04-06T18:53:33.897 回答
0

不,您必须在析构函数中为该对象显式调用 delete

于 2013-04-06T18:53:46.483 回答