C++可通过装饰器模式实现类似Python @decorator的功能,核心是组合优于继承:定义抽象接口Component,ConcreteComponent和Decorator均实现它,Decorator持std::unique_ptr转发调用并添加逻辑;支持运行时链式叠加;模板+CRTP可实现零开销静态装饰。

C++ 本身没有像 Python 那样的原生 @decorator 语法,但装饰器模式(Decorator Pattern)完全可以用标准 C++ 实现——核心是“组合优于继承”,通过包装对象,在不修改原始类代码的前提下动态添加行为。
用抽象接口 + 具体装饰器实现扩展
关键在于定义统一接口,让原始组件和所有装饰器都实现它,装饰器内部持有一个该接口的指针/引用,把调用转发出去,再在前后插入新逻辑。
- 定义抽象组件接口(如
Component),声明核心操作(如operation()) - 原始类(
ConcreteComponent)直接实现该接口 - 抽象装饰器(
Decorator)也继承自Component,并持有一个std::unique_ptr或引用 - 具体装饰器(如
LoggingDecorator、TimingDecorator)继承Decorator,重写operation():先执行附加逻辑(如打日志),再调用被包装对象的operation()
支持运行时叠加多个装饰器
因为每个装饰器只依赖 Component 接口,不关心被包装的是原始对象还是另一个装饰器,所以可以链式组合:
auto comp = std::make_unique(); auto logged = std::make_unique (std::move(comp)); auto timed = std::make_unique (std::move(logged)); timed->operation(); // 先计时 → 再日志 → 最终执行原始逻辑
这种组合方式完全静态、类型安全,无需反射或宏,也不侵入原有类定义。
立即学习“C++免费学习笔记(深入)”;
用模板 + CRTP 实现零开销装饰(进阶)
若追求极致性能且装饰逻辑固定,可用模板装饰器避免虚函数开销:
- 定义模板基类
Decorator,其中T是被装饰类型 - 装饰器成员函数直接调用
static_cast(this)->operation() - 继承时写
class LoggingDecorator : public Decorator(CRTP)
这种方式编译期绑定,无虚表、无动态分配,但灵活性略低于接口方案,适合已知装饰组合的场景。
注意生命周期与所有权管理
装饰器持有被包装对象,必须明确谁负责释放内存:
- 推荐用
std::unique_ptr表达独占所有权,构造时移动传入 - 若需共享底层对象,可用
std::shared_ptr,但要注意循环引用风险 - 避免裸指针,除非能保证被包装对象生命周期严格长于装饰器
不复杂但容易忽略。











