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

为何按C++核心准则,构造/析构函数成对用new/delete是错误?

关于C++核心准则中构造/析构函数成对使用new/delete的解释

首先纠正你的理解:这种写法并非语法上的绝对错误,但属于C核心准则明确指出的**高风险、不符合现代C最佳实践**的操作,强烈建议避免。

核心问题出在以下几点:

  • 异常安全漏洞
    如果构造函数中执行new后,后续代码抛出异常(比如另一个对象构造失败、调用的函数抛出异常),此时对象的构造并未完成,析构函数不会被调用,之前new分配的内存会直接泄漏。举个典型反例:

    class RiskyClass {
    private:
        int* num_ptr;
        ComplexObj* obj_ptr;
    public:
        RiskyClass() {
            num_ptr = new int(42); // 内存分配成功
            obj_ptr = new ComplexObj(); // 假设这里抛出异常(比如ComplexObj构造失败)
            // 到这一步,构造中断,析构函数不会执行,num_ptr的内存永久泄漏
        }
        ~RiskyClass() {
            delete num_ptr;
            delete obj_ptr;
        }
    };
    
  • 违反RAII核心原则
    C++核心准则的核心思想之一是RAII(资源获取即初始化)——让资源的生命周期与对象绑定,由对象的构造/析构自动管理资源。手动在构造里new、析构里delete,本质是放弃了RAII的安全保障,把资源管理的责任丢给了开发者,极易出错。

  • 拷贝/移动操作的隐形风险
    如果你的类没有手动实现拷贝构造、拷贝赋值、移动构造、移动赋值函数,编译器会生成默认版本,这些默认版本会做浅拷贝。如果多个对象持有同一个裸指针,当其中一个对象析构时释放了内存,其他对象的指针就会变成悬空指针,后续访问或析构都会触发未定义行为。

符合准则的正确写法

用智能指针(std::unique_ptr/std::shared_ptr)或标准容器来替代裸指针和手动内存管理:

class SafeClass {
private:
    std::unique_ptr<int> num_ptr;
    std::unique_ptr<ComplexObj> obj_ptr;
public:
    SafeClass() : num_ptr(std::make_unique<int>(42)), obj_ptr(std::make_unique<ComplexObj>()) {}
    // 不需要手动写析构函数!智能指针会在对象生命周期结束时自动释放资源
    // 默认的拷贝/移动操作被禁用,避免浅拷贝风险;如需支持可手动实现
};

如果需要管理动态数组,直接用std::vector代替new[]和delete[],同样能自动处理内存分配与释放。

内容的提问来源于stack exchange,提问作者Mangy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 15:23:09