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

C++拷贝构造函数:尝试引用已删除函数问题咨询

问题分析与解决方案

嘿,我来帮你拆解一下这个问题,其实是两个小坑凑到一起导致的报错~

核心错误原因

  1. std::make_shared触发了被删除的拷贝构造函数
    当你尝试用std::make_shared<classA>(ca)创建智能指针时,make_shared会把你传入的栈上对象ca拷贝一份到它管理的堆内存中,这一步必须调用classA的拷贝构造函数。但你已经明确用classA(const classA&) = delete;禁用了这个函数,编译器自然会抛出"attempting to reference a deleted function"的错误。

  2. classA没有可用的默认构造函数
    因为你自定义了析构函数,并且显式删除了拷贝构造函数,C++编译器不会再自动生成默认构造函数。所以你写的classA ca;这行代码本身就无法通过编译——编译器找不到能用来构造ca的构造函数。

修复方案

方案一:直接用make_shared构造堆上对象(推荐)

既然用了std::shared_ptr,最佳实践就是直接在堆上构造对象,彻底避开拷贝操作。同时给classA补上默认构造函数,避免内存悬空问题:

#include <memory>

class classA {
private:
    char* data;
public:
    // 显式定义默认构造函数,初始化data为nullptr
    classA() : data(nullptr) {}
    
    // 保持拷贝构造函数禁用
    classA(const classA&) = delete;
    
    ~classA() { 
        delete[] data; // delete[] nullptr是安全的,无需额外判断
    }
};

class classB {
private:
    std::shared_ptr<classA> ptrA;
public:
    classB(std::shared_ptr<classA> sp) : ptrA(sp) {}
};

int main() {
    // 直接通过make_shared在堆上构造classA,无需拷贝
    classB cb(std::make_shared<classA>());
    return 0;
}

方案二:如果需要接管已有对象(不推荐)

如果你确实有一个已存在的classA实例要交给shared_ptr管理,可以直接用shared_ptr的构造函数(而非make_shared),但注意必须是堆上对象(栈上对象会导致重复析构崩溃):

// 创建堆上的classA实例
classA* raw_ptr = new classA();
// 用shared_ptr接管这个对象的生命周期
classB cb(std::shared_ptr<classA>(raw_ptr));

额外优化建议

你的classA里用了char* data手动管理内存,其实可以换成std::string,这样完全不需要自己写析构函数,也能避免内存泄漏、悬空指针等问题,代码会简洁很多:

#include <memory>
#include <string>

class classA {
private:
    std::string data; // 替换char*为std::string
public:
    classA(const classA&) = delete;
    // 编译器会自动生成默认构造、析构等函数,无需手动编写
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:10:47