如何实现仅可通过std::shared_ptr管理、析构函数私有类?
当然可以不借助DestructorHelper实现需求,以下是两种更简洁优雅的方案,既能保证类只能通过std::shared_ptr管理,又能满足多线程传递时的生命周期管理要求:
方案一:利用类的静态私有删除函数
class SharedOnly { public: // 禁用所有拷贝/移动语义,避免对象被复制或移动 SharedOnly(const SharedOnly&) = delete; SharedOnly& operator=(const SharedOnly&) = delete; SharedOnly(SharedOnly&&) = delete; SharedOnly& operator=(SharedOnly&&) = delete; // 唯一的对象创建入口 static std::shared_ptr<SharedOnly> create() { return std::shared_ptr<SharedOnly>(new SharedOnly(), &SharedOnly::destroy); } private: // 私有构造函数,外部无法直接创建对象 SharedOnly() = default; // 私有析构函数,外部无法直接销毁对象 ~SharedOnly() = default; // 静态私有删除器,仅类内部可访问,用于std::shared_ptr销毁对象 static void destroy(SharedOnly* ptr) { delete ptr; } };
原理说明
- 将删除器
destroy设为类的静态私有成员,它天然具备访问类私有析构函数的权限,无需额外的友元结构体。 std::shared_ptr在最后一个实例销毁时,会调用传入的destroy函数完成对象清理,完全符合生命周期管理要求。
方案二:利用成员函数内的lambda作为删除器(最简洁)
class SharedOnly { public: // 禁用所有拷贝/移动语义 SharedOnly(const SharedOnly&) = delete; SharedOnly& operator=(const SharedOnly&) = delete; SharedOnly(SharedOnly&&) = delete; SharedOnly& operator=(SharedOnly&&) = delete; static std::shared_ptr<SharedOnly> create() { return std::shared_ptr<SharedOnly>(new SharedOnly(), [](SharedOnly* ptr) { delete ptr; }); } private: SharedOnly() = default; ~SharedOnly() = default; };
原理说明
- 定义在类的静态成员函数
create内部的lambda,继承了成员函数的访问权限,能够直接调用类的私有析构函数。 - 这种方案彻底消除了冗余代码,实现了最紧凑的逻辑,同时完全满足需求。
多线程安全性说明
std::shared_ptr的引用计数操作是原子性的,多个线程持有指向同一对象的不同std::shared_ptr实例时,引用计数的增减无需额外同步,因此该类可以安全地在多线程间传递,确保仅当最后一个std::shared_ptr销毁时,对象才会被析构。
内容的提问来源于stack exchange,提问作者Chaitanya
相关产品推荐
相关产品推荐

