代理类必须继承同一接口,否则无法替换真实对象;需通过抽象基类定义纯虚函数实现多态,Proxy与RealSubject均须public继承并重写所有纯虚函数;代理内部应使用智能指针管理真实对象生命周期,并在成员函数中添加前置/后置逻辑,保持const正确性与函数签名一致。

代理类必须继承同一接口,否则无法替换真实对象
代理模式的核心是“用代理对象控制对真实对象的访问”,C++里靠接口(抽象基类)实现多态。如果 Proxy 和 RealSubject 没有共同的虚基类,就无法在调用处用 Subject* 统一接收,也就谈不上“透明替换”。
- 接口必须定义纯虚函数,比如
virtual void request() = 0; -
RealSubject和Proxy都要 public 继承该接口,且重写所有纯虚函数 - 不能只靠名字一致——C++不支持鸭子类型,没继承关系就编译不过
代理类内部持有真实对象指针,推荐用智能指针管理生命周期
手动 new/delete 容易导致内存泄漏或悬空指针,尤其当代理被频繁复制或传递时。直接裸指针传入也容易出错。
- 用
std::unique_ptr<subject></subject>或std::shared_ptr<subject></subject>成员变量保存真实对象 - 构造函数接受
std::unique_ptr<subject>&&</subject>或std::shared_ptr<subject></subject>,避免拷贝 - 若真实对象由外部创建且生命周期明确,也可用引用(
Subject&),但代理不能比真实对象活得久
前置/后置逻辑写在代理的成员函数里,别动真实对象的实现
代理的价值在于不修改 RealSubject 就能增加日志、权限检查、缓存等行为。所有增强逻辑都应放在 Proxy::request() 等函数体内,而不是去改 RealSubject::request()。
- 典型结构:前置操作 →
m_real->request()→ 后置操作 - 注意异常安全:如果前置操作可能抛异常,确保不会跳过资源清理;建议用 RAII 封装前置动作(如日志开始/结束)
- 不要在代理里重复实现业务逻辑——那是真实对象的事
小心 const 正确性与函数重载,否则代理会静默失效
如果接口函数声明为 const,而代理的对应函数没加 const,编译器会认为这是重载而非重写,导致多态调用失败,运行时仍走基类默认实现(如果有)或报错。
立即学习“C++免费学习笔记(深入)”;
- 接口中是
virtual void request() const = 0;,则Proxy::request()必须也带const - 参数类型、const 性、noexcept 修饰符都要完全一致,否则不是 override
- 用
override关键字强制检查,比如void request() const override,编译器会立刻报错提醒


















