C++中析构函数与delete()的执行顺序及正确用法咨询
关于delete()与析构函数的用法疑问及解答
很多资料都说delete()会调用对象的析构函数,但你提供的智能指针示例代码里,却在析构函数内部调用了delete()。想请教下:对象在栈和堆上初始化时,delete()的正确用法是什么?
先理清核心逻辑
首先明确两个关键行为:
- 对堆上对象的指针调用
delete ptr时,会先执行该对象的析构函数,再释放指针指向的堆内存。 - 栈上的对象会在离开作用域时自动触发析构函数,完全不需要手动调用
delete。
示例代码的合理性解释
你贴的这个智能指针类,核心是帮我们管理堆内存的生命周期:
- 构造函数接收一个用
new分配的int*指针(比如new int()返回的地址),把它存在成员变量ptr里。 - 当栈上的
SmartPtr对象(比如main里的ptr)离开main函数的作用域时,会自动调用~SmartPtr()析构函数,此时在析构函数里调用delete (ptr),是为了释放之前new出来的那个int的堆内存。 - 这里要注意:
delete操作的是成员变量里的int*,不是SmartPtr对象本身——SmartPtr是栈对象,根本不能用delete去操作它。
栈/堆对象的delete用法总结
栈上对象
- 栈对象是在栈内存中分配的(比如
SmartPtr ptr(new int())里的ptr),作用域结束时会自动调用析构函数并释放内存。 - 绝对不能对栈对象调用
delete,这属于未定义行为,大概率会导致程序崩溃。
堆上对象
- 堆对象必须用
new关键字分配(比如new int()、new SmartPtr()),用完后必须手动调用delete来触发析构+释放内存。 - 举个例子:如果是
SmartPtr* sp = new SmartPtr(new int()),那你需要手动执行delete sp——此时会先调用~SmartPtr()析构函数(释放内部托管的int内存),再释放sp指向的SmartPtr对象的堆内存。
示例代码
#include <iostream> using namespace std; class SmartPtr { int* ptr; // 实际指向堆内存的指针 public: // 构造函数,explicit关键字防止隐式转换 explicit SmartPtr(int* p = NULL) { ptr = p; } // 析构函数:负责释放托管的堆内存 ~SmartPtr() { delete (ptr); } // 重载解引用运算符,让智能指针可以像普通指针一样使用 int& operator*() { return *ptr; } }; int main() { SmartPtr ptr(new int()); *ptr = 20; cout << *ptr; // 无需手动delete ptr:当ptr离开main作用域时,析构函数自动调用,释放内部的堆内存 return 0; }
内容的提问来源于stack exchange,提问作者Xfce4
相关产品推荐
相关产品推荐

