1. 原型模式在C++中的核心概念
原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有对象来创建新对象,而不是通过构造函数。这种模式特别适用于以下场景:
- 对象创建成本较高(如需要进行复杂计算或资源密集型操作)
- 系统需要独立于其对象的创建、组合和表示方式
- 需要避免使用与产品类层次平行的工厂类层次
在C++中实现原型模式通常涉及以下关键组件:
- 抽象原型类(Prototype):声明克隆接口的抽象基类
- 具体原型类(ConcretePrototype):实现克隆操作的具体类
- 客户端(Client):通过请求原型克隆新对象
注意:C++中的克隆操作需要考虑深拷贝与浅拷贝的问题,特别是在对象包含指针成员时。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 经典原型模式的C++实现
让我们先看一个最基本的原型模式实现示例:
cpp复制#include <iostream>
#include <memory>
#include <string>
// 抽象原型类
class Prototype {
public:
virtual ~Prototype() = default;
virtual std::unique_ptr<Prototype> clone() const = 0;
virtual void printInfo() const = 0;
};
// 具体原型类
class ConcretePrototype : public Prototype {
public:
ConcretePrototype(int id, std::string name)
: m_id(id), m_name(std::move(name)) {}
// 实现克隆方法
std::unique_ptr<Prototype> clone() const override {
return std::make_unique<ConcretePrototype>(*this);
}
void printInfo() const override {
std::cout << "ID: " << m_id << ", Name: " << m_name << std::endl;
}
void setName(const std::string& name) {
m_name = name;
}
private:
int m_id;
std::string m_name;
};
int main() {
// 创建原型对象
auto prototype = std::make_unique<ConcretePrototype>(1, "Original");
// 克隆对象
auto clone = prototype->clone();
// 修改克隆对象
dynamic_cast<ConcretePrototype*>(clone.get())->setName("Clone");
// 输出信息
prototype->printInfo(); // 输出: ID: 1, Name: Original
clone->printInfo(); // 输出: ID: 1, Name: Clone
return 0;
}
这个实现展示了原型模式的基本结构,但实际应用中我们可能需要考虑更多复杂情况。
3. C++原型模式的常见变体
3.1 注册表模式(Prototype Registry)
注册表模式通过维护一个原型对象的注册表来简化对象的创建过程:
cpp复制#include <unordered_map>
#include <functional>
class PrototypeRegistry {
public:
using PrototypeFactory = std::function<std::unique_ptr<Prototype>()>;
void registerPrototype(const std::string& key, PrototypeFactory factory) {
m_registry[key] = std::move(factory);
}
std::unique_ptr<Prototype> create(const std::string& key) {
auto it = m_registry.find(key);
if (it != m_registry.end()) {
return it->second();
}
return nullptr;
}
private:
std::unordered_map<std::string, PrototypeFactory> m_registry;
};
// 使用示例
PrototypeRegistry registry;
registry.registerPrototype("default", []() {
return std::make_unique<ConcreteProtot
