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(); // 先计时 → 再日志 → 最终执行原始逻辑
这种组合方式完全静态、类型安全,无需反射或宏,也不侵入原有类定义。
若追求极致性能且装饰逻辑固定,可用模板装饰器避免虚函数开销:
Decorator,其中 T 是被装饰类型static_cast(this)->operation()
class LoggingDecorator : public Decorator(CRTP)这种方式编译期绑定,无虚表、无动态分配,但灵活性略低于接口方案,适合已知装饰组合的
场景。
装饰器持有被包装对象,必须明确谁负责释放内存:
std::unique_ptr 表达独占所有权,构造时移动传入std::shared_ptr,但要注意循环引用风险不复杂但容易忽略。