问题:Point是一个类,Point pt(1, 2); Point * ppt = new Point(31, 32); 这两种创建对象的方式有什么区别,他们分别存储在哪个区域?
class Point
{
public:
Point(int ix = 0, int iy = 0)
: _ix(ix)
, _iy(iy)
{
cout << "Point(int,int)" << endl;
}
void print() {
cout << "(" << _ix
<< "," << _iy
<< ")" << endl;
}
~Point() { cout << "~Point()" << endl; }
private:
int _ix;
int _iy;
};
在C++中,Point pt(1, 2);
和 Point * ppt = new Point(31, 32);
这两种创建对象的方式有本质的区别,主要体现在对象的存储位置、生命周期和资源管理上。
对象存储区域
-
自动变量(Automatic Variable):
当你使用Point pt(1, 2);
的形式创建一个对象时,这个对象被存储在**栈(Stack)**上。这意味着:- 它的内存是自动分配和释放的。
- 它的生命周期仅限于当前的作用域(例如,在函数内部声明的pt,在函数退出后将自动销毁)。
-
动态分配的对象(Dynamically Allocated Object):
而当你使用Point * ppt = new Point(31, 32);
创建一个对象时,这个对象被存储在**堆(Heap)**上。这表示:- 内存需要手动分配(通过
new
)和释放(通常通过delete
)。 - 它的生命周期直到程序结束或者手动调用
delete
才会结束。
- 内存需要手动分配(通过
生命周期与资源管理
-
栈上的对象: 生命周期受作用域控制,超出作用域后自动销毁,不需要手动管理内存。
-
堆上的对象: 生命周期不受作用域限制,必须显式地使用
delete
操作符来释放内存。如果忘记释放,会导致内存泄漏。
总结
- 使用
Point pt(1, 2);
创建的对象更简单,易于管理,适用于生命周期可以预测的情况。 - 使用
Point * ppt = new Point(31, 32);
创建的对象提供了更多的灵活性,但需要程序员负责内存的释放,避免内存泄漏。
在现代C++中,为了更好地管理资源,推荐使用智能指针如std::unique_ptr
或std::shared_ptr
来代替原始指针,这样可以自动管理堆上对象的生命周期,减少内存泄漏的风险。例如:
#include <memory>
std::unique_ptr<Point> ppt(new Point(31, 32));
这里std::unique_ptr
会在离开作用域时自动删除它所管理的Point
对象,无需手动调用delete
。