You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 06:33:25