如何仅允许通过父类对象创建子类Child的实例?
解决方案:利用友元+私有构造实现严格的工厂创建限制
这是个典型的工厂模式应用场景,咱们可以通过C++的访问控制和友元机制完美实现需求,具体步骤和代码如下:
核心思路
- 把
Child的所有构造入口(包括默认构造、拷贝/移动构造、赋值运算符)全部设为private,从根源上禁止外部代码直接创建实例,同时也自然禁用了默认构造方式——因为显式声明私有构造后,编译器不会自动生成公有的默认构造。 - 让
Parent类成为Child的友元,这样Parent的createChild()方法就能合法访问Child的私有构造函数,成为唯一的实例创建入口。
完整代码示例
#include <memory> // 如果用智能指针的话需要加这个头 class Parent { public: // 两种返回方式可选:直接返回对象,或者返回智能指针(更推荐后者) Child createChild(); std::unique_ptr<Child> createChildPtr(); // 此处可添加成员数据与函数 }; class Child : public Parent { // 授予Parent类访问私有成员的权限 friend class Parent; private: // 显式声明私有默认构造,禁用外部直接实例化 Child() = default; // 可选:如果要彻底禁止通过拷贝/移动创建新实例,就禁用这些 Child(const Child&) = delete; Child(Child&&) = delete; Child& operator=(const Child&) = delete; Child& operator=(Child&&) = delete; // 此处可添加成员数据与函数 }; // 实现返回对象的版本 Child Parent::createChild() { return Child(); // 友元关系允许调用私有构造 } // 实现返回智能指针的版本(更灵活,避免对象拷贝) std::unique_ptr<Child> Parent::createChildPtr() { return std::make_unique<Child>(); }
细节说明
- 为什么要禁用拷贝/移动?
如果需求是仅允许通过createChild()创建实例,那必须禁用拷贝和移动——不然用户拿到一个Child实例后,就能通过复制或移动生成新的实例,绕开了工厂限制。如果业务允许拷贝实例,可以保留这些操作,根据实际需求调整。 - 智能指针版本的优势
返回std::unique_ptr可以避免对象拷贝开销,同时明确所有权转移,更符合现代C++的编码习惯,也能方便地管理动态分配的实例生命周期。
内容的提问来源于stack exchange,提问作者Sooraj
相关产品推荐
相关产品推荐

