C++拷贝构造函数:尝试引用已删除函数问题咨询
问题分析与解决方案
嘿,我来帮你拆解一下这个问题,其实是两个小坑凑到一起导致的报错~
核心错误原因
std::make_shared触发了被删除的拷贝构造函数
当你尝试用std::make_shared<classA>(ca)创建智能指针时,make_shared会把你传入的栈上对象ca拷贝一份到它管理的堆内存中,这一步必须调用classA的拷贝构造函数。但你已经明确用classA(const classA&) = delete;禁用了这个函数,编译器自然会抛出"attempting to reference a deleted function"的错误。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
相关产品推荐
相关产品推荐

