1. 设计模式在C++中的实现概述
设计模式是软件开发中经过验证的解决方案模板,用于解决特定场景下的常见问题。在C++中实现设计模式需要考虑语言特性(如多继承、模板、RAII等)与性能要求。与Java/C#等语言相比,C++的实现往往更注重内存管理和运行时效率。
我在工业级C++项目中实践设计模式多年,发现三大核心价值:
- 提升代码复用性:通过模式化的设计减少重复劳动
- 增强系统扩展性:符合开闭原则的设计使修改影响最小化
- 改善团队协作:标准化的设计词汇表加速沟通
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 创建型模式实现要点
2.1 单例模式的双重检查锁定
C++11后的标准实现:
cpp复制class Singleton {
private:
static std::atomic<Singleton*> instance;
static std::mutex mtx;
Singleton() = default;
public:
static Singleton* getInstance() {
Singleton* tmp = instance.load(std::memory_order_acquire);
if (tmp == nullptr) {
std::lock_guard<std::mutex> lock(mtx);
tmp = instance.load(std::memory_order_relaxed);
if (tmp == nullptr) {
tmp = new Singleton();
instance.store(tmp, std::memory_order_release);
}
}
return tmp;
}
};
关键细节:
- 使用atomic保证可见性
- memory_order参数优化性能
- 构造函数私有化防止外部实例化
注意:早期C++版本需要volatile修饰,但在C++11后应优先使用atomic
2.2 工厂方法模式与抽象工厂
典型UML关系:
code复制Creator -> Product
ConcreteCreator -> ConcreteProduct
模板实现技巧:
cpp复制template<typename T>
class Creator {
public:
virtual std::unique_ptr<T> create() = 0;
};
class WidgetFactory : public Creator<Widget> {
public:
std::unique_ptr<Widget> create() override {
return std::make_unique<ConcreteWidget>();
}
};
3. 结构型模式实践
3.1 适配器模式的双向适配
对象适配器实现:
cpp复制class LegacyRect {
public:
void draw(int x1, int y1, int x2, int y2);
};
class ModernRect {
public:
void draw(Point topLeft, Point bottomRight);
};
class RectAdapter : public ModernRect {
private:
LegacyRect adaptee;
public:
void draw(Point topLeft, Point bottomRight) override {
adaptee.draw(topLeft.x, topLeft.y,
bottomRight.x, bottomRight.y);
}
};
3.2 组合模式的透明实现
统一接口设计:
cpp复制class Component {
public:
virtual void operation() = 0;
virtual void add(Component*) { throw std::runtime_error("Unsupported"); }
virtual void remove(Component*) { throw std::runtime_error("Unsupported"); }
virtual ~Component() = default;
};
class Leaf : public Component {
public:
void operation() override { /*...*/ }
};
class Composite : public Component {
private:
std::vector<Component*> children;
public:
void operation() override {
for (auto child : children) {
child->operation();
}
}
void add(Component* c) override { children.push_back(c); }
void remove(Component* c) override { /*...*/ }
};
4. 行为型模式深度解析
4.1 观察者模式的事件总线
现代C++实现方案:
cpp复制class EventBus {
std::unordered_map<std::type_index,
std::vector<std::function<void(const void*)>>> handlers;
public:
template<typename Event>
void publish(const Event& event) {
auto it = handlers.find(typeid(Event));
if (it != handlers.end()) {
for (auto& handler : it->second) {
handler(&event);
}
}
}
template<typename Event>
auto subscribe(std::function<void(const Event&)> handler) {
std::type_index type = typeid(Event);
handlers[type].emplace_back(
[handler](const void* event) {
handler(*static_cast<const Event*>(event));
});
return handlers[type].size() - 1;
}
};
4.2 策略模式的模板特化
编译期策略选择:
cpp复制template<typename Strategy>
class Context {
Strategy strategy;
public:
void execute() { strategy.doAlgorithm(); }
};
struct FastStrategy {
void doAlgorithm() { /* 快速算法 */ }
};
struct PreciseStrategy {
void doAlgorithm() { /* 精确算法 */ }
};
// 使用示例
Context<FastStrategy> ctx;
ctx.execute();
5. 模式混合应用案例
5.1 状态机模式组合
有限状态机实现:
cpp复制class State {
public:
virtual void enter() {}
virtual void exit() {}
virtual void update() = 0;
};
class StateMachine {
private:
std::unordered_map<std::string, std::unique_ptr<State>> states;
State* current = nullptr;
public:
template<typename T>
void addState(const std::string& name) {
states[name] = std::make_unique<T>();
}
void transitionTo(const std::string& name) {
if (current) current->exit();
current = states[name].get();
current->enter();
}
void update() {
if (current) current->update();
}
};
5.2 命令模式的撤销栈
可撤销操作实现:
cpp复制class Command {
public:
virtual void execute() = 0;
virtual void undo() = 0;
virtual ~Command() = default;
};
class CommandHistory {
private:
std::stack<std::unique_ptr<Command>> history;
public:
void execute(std::unique_ptr<Command> cmd) {
cmd->execute();
history.push(std::move(cmd));
}
void undo() {
if (!history.empty()) {
history.top()->undo();
history.pop();
}
}
};
6. 性能优化技巧
6.1 对象池模式实现
内存池优化示例:
cpp复制template<typename T>
class ObjectPool {
private:
std::vector<std::unique_ptr<T>> pool;
std::size_t nextAvailable = 0;
public:
template<typename... Args>
void preallocate(std::size_t count, Args&&... args) {
for (std::size_t i = 0; i < count; ++i) {
pool.emplace_back(std::make_unique<T>(std::forward<Args>(args)...));
}
}
T* acquire() {
if (nextAvailable >= pool.size()) {
return nullptr;
}
return pool[nextAvailable++].get();
}
void releaseAll() {
nextAvailable = 0;
}
};
6.2 享元模式的内存优化
纹理共享实现:
cpp复制class Texture {
// 内部状态
std::string filePath;
// 外部状态
struct RenderParams {
int x, y;
float scale;
};
public:
void render(const RenderParams& params) {
// 使用外部状态渲染
}
};
class TextureFactory {
private:
std::unordered_map<std::string, std::shared_ptr<Texture>> cache;
public:
std::shared_ptr<Texture> getTexture(const std::string& path) {
auto it = cache.find(path);
if (it == cache.end()) {
it = cache.emplace(path, std::make_shared<Texture>(path)).first;
}
return it->second;
}
};
7. 现代C++特性应用
7.1 访问者模式的变体实现
使用std::variant:
cpp复制using Shape = std::variant<Circle, Square, Triangle>;
class ShapeVisitor {
public:
void operator()(const Circle& c) { /*...*/ }
void operator()(const Square& s) { /*...*/ }
void operator()(const Triangle& t) { /*...*/ }
};
void processShapes(const std::vector<Shape>& shapes) {
ShapeVisitor visitor;
for (const auto& shape : shapes) {
std::visit(visitor, shape);
}
}
7.2 装饰器模式的CRTP应用
编译期装饰:
cpp复制template<typename T>
class Decorator : public T {
public:
template<typename... Args>
Decorator(Args&&... args) : T(std::forward<Args>(args)...) {}
void operation() {
preOperation();
T::operation();
postOperation();
}
private:
void preOperation() { /*...*/ }
void postOperation() { /*...*/ }
};
8. 设计模式反模式警示
8.1 过度设计的识别特征
常见症状包括:
- 为简单if-else引入策略模式
- 在不会扩展的场景使用工厂模式
- 为单方法接口创建命令对象
8.2 模式滥用的重构策略
重构步骤示例:
- 识别模式引入的间接层
- 评估模式带来的维护成本
- 考虑简单函数/模板替代方案
- 测量性能影响(特别是虚函数调用)
9. 测试与调试技巧
9.1 观察者模式的单元测试
模拟对象实现:
cpp复制class MockObserver : public IObserver {
public:
MOCK_METHOD(void, update, (const Event&), (override));
};
TEST(SubjectTest, NotifiesAllObservers) {
Subject subject;
MockObserver obs1, obs2;
subject.attach(&obs1);
subject.attach(&obs2);
EXPECT_CALL(obs1, update(_)).Times(1);
EXPECT_CALL(obs2, update(_)).Times(1);
subject.notify(Event{});
}
9.2 模板方法模式的调试
断点设置策略:
- 在抽象基类的模板方法设断点
- 观察各hook方法的调用顺序
- 检查各步骤的前置/后置条件
10. 工业级应用建议
10.1 线程安全模式实现
读写锁保护共享资源:
cpp复制class ThreadSafeSingleton {
private:
static std::shared_ptr<ThreadSafeSingleton> instance;
static std::shared_mutex mtx;
ThreadSafeSingleton() = default;
public:
static std::shared_ptr<ThreadSafeSingleton> getInstance() {
std::shared_lock readLock(mtx);
if (!instance) {
readLock.unlock();
std::unique_lock writeLock(mtx);
if (!instance) {
instance.reset(new ThreadSafeSingleton());
}
}
return instance;
}
};
10.2 模式组合的最佳实践
推荐组合方案:
- 工厂方法+原型模式:动态创建对象副本
- 策略+装饰器:运行时算法扩展
- 观察者+中介者:解耦复杂事件处理
在大型C++项目中,我通常会在架构设计阶段预留约30%的模式扩展空间,通过接口隔离和依赖注入保持系统弹性。实际编码时,建议先用简单实现验证需求,再逐步引入必要模式,避免前期过度设计。
