C++原型模式通过抽象基类声明clone()接口,具体类实现深拷贝逻辑,可选原型管理器按名注册与克隆,核心是对象自主克隆以解耦构造细节。

在 C++ 中实现原型模式,核心是让对象能“克隆自己”——通过定义一个统一的克隆接口,并由具体类自行实现深拷贝逻辑,从而避免紧耦合于构造细节,支持运行时动态创建类型未知的对象。
1. 原型基类:定义克隆接口
声明一个抽象基类(如 Prototype),提供纯虚函数 clone()。它不关心怎么复制,只约定“你能复制出一个新对象”。
注意:返回类型通常用智能指针(如 std::unique_ptr
示例:
立即学习“C++免费学习笔记(深入)”;
class Prototype {
public:
virtual ~Prototype() = default;
virtual std::unique_ptr clone() const = 0;
};
2. 具体原型类:实现深拷贝逻辑
每个可被克隆的具体类(如 ConcretePrototypeA)继承基类,重写 clone(),在其中调用自身构造函数或手动复制成员变量。
若含指针、容器、资源句柄等,必须做深拷贝;否则默认拷贝构造可能引发浅拷贝问题(如双释放、悬空指针)。
示例(含动态分配成员):
原本这个程序只是本人两年前初学时练手的,最近拿出来进行了修改,所以叫XmxCms 企业网站管理系统2.0 开发环境:WinXP + VS2008 + SQLServer 2008 + Access开发语言:C#本程序采用 三层架构 + 抽象工厂设计模式 + Linq 实现,目前只做了Access 和 SQL Server ,默认数据库为Access,要更换数据库只需修改web.config 即可
class ConcretePrototypeA : public Prototype {
private:
int value_;
std::string* data_; // 动态分配,需深拷贝
public:
ConcretePrototypeA(int v, const std::string& s)
: value(v), data(new std::string(s)) {}
// 深拷贝实现
std::unique_ptr clone() const override {
return std::make_unique(*this);
}
// 自定义拷贝构造(确保深拷贝 data_)
ConcretePrototypeA(const ConcretePrototypeA& other)
: value_(other.value_),
data_(other.data_ ? new std::string(*other.data_) : nullptr) {}
~ConcretePrototypeA() { delete data_; }
};
3. 原型管理器(可选但实用):集中注册与获取
用一个简单注册表(如 std::map<:string std::unique_ptr>>)缓存原型实例,客户端通过字符串 ID 获取并克隆,解耦创建逻辑。
适用于需要按名动态生成多种类型的场景(如配置驱动的对象工厂)。
示例简版:
class PrototypeRegistry {
private:
std::map> prototypes_;
public:
void registerPrototype(const std::string& name, std::uniqueptr proto) {
prototypes [name] = std::move(proto);
}
std::unique_ptr create(const std::string& name) const {
auto it = prototypes_.find(name);
return (it != prototypes_.end()) ? it->second->clone() : nullptr;
}
};
// 使用:
PrototypeRegistry registry;
registry.registerPrototype("A", std::make_unique(42, "hello"));
auto obj = registry.create("A"); // 得到一份独立副本
4. 注意事项与常见坑
原型模式不是万能的,C++ 实现中需特别留意:
-
拷贝语义必须明确:如果类有自定义析构/赋值/移动操作,拷贝构造函数务必正确实现深拷贝,否则
clone()会失效 -
避免裸指针管理:优先用
std::unique_ptr或std::shared_ptr返回克隆结果,防止内存泄漏或误删 -
const 正确性:
clone()声明为const成员函数,表示克隆不改变原对象状态 - 不依赖 RTTI 或反射:C++ 没有内置类型名自动构造,所有原型都需提前注册或硬编码创建
原型模式在 C++ 中本质是“面向对象的拷贝抽象”,它把“怎么造一个新对象”的决策权交给对象自身,适合配置化、插件化或需大量相似对象的系统。不复杂但容易忽略深拷贝细节,写对了就非常稳健。










