如果我在不使用new关键字的情况下创建对象,例如'Object s(someval)',但是对象构造函数使用new,那么当该对象超出范围时,是否会为它的新分配调用析构函数?我觉得好像是,但我不确定。
答案 0 :(得分:3)
让我们给对象命名,不管吗?
struct A {
A() b(new B) {}
B* b;
C c;
};
A a;
此处,a
的析构函数被调用。 A::c
的析构函数(在a
被破坏时自动调用)也是如此。
然而,*A::b
的析构函数不被调用 - 实际上,指针对象A::b
本身已正确释放,但因为它是一个原语类型(它是一个指针!)没有任何反应。然而,指针 *A::b
需要通过调用delete
来手动破坏(并释放其内存)。
答案 1 :(得分:2)
当该对象超出范围时,是否会为析构函数的新分配调用它?
这取决于Object
的定义方式。
如果new
返回的指针存储在Object
的某些数据成员中,delete
本身的析构函数调用Object
,则是,当new
超出范围时,分配有s
的对象也将被销毁。
否则,没有。在丢失对分配对象的最后一个指针/引用之前,对new
的每次调用必须与对delete
的相应调用匹配,否则您将有内存泄漏。 / p>
由于很容易失败,并且由于错误地将指针悬挂(即指向寿命已经结束的对象)也很容易取消引用,因此通常优选避免执行通过原始指针new
和delete
(或它们的数组对应物)进行手动内存管理。
当您需要控制对象的生命周期时,总是更喜欢使用RAII包装器,例如std::shared_ptr<>
或std::unique_ptr<>
,除非您真的知道自己在做什么,否则无法做到
答案 2 :(得分:0)
不,如果将动态分配的指针存储为数据成员,则必须在析构函数中显式delete
它。这也引入了三条规则(C ++ 11中的五条规则),这是一个麻烦。这就是为什么在可能的情况下应该首选堆栈分配的对象。
当需要指针时,对于动态分配的数组或智能指针(例如std::vector
或std::unique_ptr
),使用RAII包装器(例如std::shared_ptr
)单个动态分配的对象。这些为你和你管理记忆,这不是额外的工作。
答案 3 :(得分:0)
不,它不会......
您必须使用delete
在分配的对象的析构函数中定义new
。
您使用new
在堆上创建一个对象,当您的对象被销毁时,您将丢失对该对象的引用,从而导致内存泄漏。
为避免这种情况,您可以使用类似shared_ptr
的智能指针。
答案 4 :(得分:0)
否则您必须在析构函数
中为该对象显式调用delete