所以在C ++中如果我创建一个使用new
的对象,我应该总是使用delete
解除分配。
例如
Segment::Segment(float length)
{
segmentLength = length;
angle = 0.0f;
x = Rand::randFloat(1.0f, 1.5f);
y = Rand::randFloat(1.0f, 1.5f);
vx = Rand::randFloat(0.0f, 1.0f);
vy = Rand::randFloat(0.0f, 1.0f);
prevX = Rand::randFloat(0.0f, 1.0f);
prevX = Rand::randFloat(0.0f, 1.0f);
};
让我说我在另一个类中使用它,例如,
this._segmentObject = Segment(2.0f);
this._segmentPointer = new Segment(2.0f);
在该类的析构函数中,我知道我应该在this._segmentPointer上调用delete
,但是如何确保为另一个内存释放内存?
答案 0 :(得分:5)
但是如何确保为另一个内存释放内存?
这是自动的。这就是为什么这种类型的存储被称为自动。自动存储在存储生命周期结束时释放,对象的析构函数称为。
当程序控件离开已分配对象的范围时,对象生命周期结束。
答案 1 :(得分:4)
当对象超出范围时,未分配new
,new[]
或malloc
系列的内容应被销毁并“释放”。
这通常意味着代码已经到达它声明的块的末尾,或者它所在的对象被破坏(以这种或那种方式)。
要看到这一点,你可以这样做:
struct C {
C() { std::cout << "C()" << std::endl; }
~C() { std::cout << "~C()" << std::endl; }
};
struct B {
B() { std::cout << "B()" << std::endl; }
~B() { std::cout << "~B()" << std::endl; }
private:
C c_;
};
struct A {
A() { std::cout << "A()" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
};
int main() {
B *b = new B; // prints "B()", also constructs the member c_ printing "C()"
{ // starts a new block
A a; // prints "A()";
} // end of block and a's scope, prints "~A()"
delete b; // prints "~B()", also destructs member c_, printing "~C()"
}
注意:如果我们没有delete b
,则“~B()”和“~C()”将永远不会打印。同样,如果c_
是分配有new
的指针,则需要delete
'才能打印“~C()”
答案 2 :(得分:3)
this._segmentObject的内存是包含对象内存的一部分,并在包含对象被销毁时释放。
this._segmentObject是从堆栈上创建的临时对象中分配的,并在超出范围时被删除。
答案 3 :(得分:1)
不仅如此,您只应在构造函数或析构函数中使用new和deallocate with delete进行分配,否则如果抛出异常,您的程序可能会泄漏。
答案 4 :(得分:1)
在销毁主类时调用所有类类型成员对象的析构函数。因此,在堆栈上分配的this
对象将在超出范围时调用析构函数。那时,除了this
对象的析构函数之外,this
对象的任何类型成员对象都将调用自己的析构函数,这些析构函数将在成员指针上调用delete
。
例如,请使用以下代码示例:
#include <iostream>
using namespace std;
class A
{
public:
A() {}
~A() { cout << "Destructor for class A called" << endl; }
};
class B
{
private:
A a;
public:
B() {}
~B() { cout << "Destructor for class B called" << endl; }
};
int main()
{
B b;
return 0;
}
运行时,输出变为以下内容:
Destructor for class B called
Destructor for class A called
所以你可以看到,当b
(在堆栈上分配)超出main
末尾时,会调用类B
的析构函数,反过来,在执行析构函数体之后,为其任何类类型成员数据对象调用析构函数,在这种情况下,它将表示类A
的析构函数。因此,在您的情况下,指针将在delete
类的析构函数中调用this
,然后在_segmentObject
的析构函数之后调用this
的析构函数已经完成了析构函数体的执行。然后,一旦调用了所有非静态数据成员对象的析构函数,this
的析构函数就会返回。
答案 5 :(得分:0)
_segmentObject在堆栈上自动分配。 当变量超出范围时,将自动调用对象析构函数。
答案 6 :(得分:0)
正如其他人所说,你不需要明确地做任何事情来回收this._segmentObject
使用的内存。一旦超出范围,内存将被回收。
目前尚不清楚为何会以两种方式使用Segment
。您应该尝试确保使用Resource Acquisition Is Initialization惯用法,因为它消除了检查new
/ delete
对的大部分需求。也就是说,只使用this._segmentObject
版本,而不是指针。
但您的申请可能不允许这样做。