将一个类的接口转换成客户端所期望的另一个接口,使原本因接口不兼容而不能一起工作的类可以协同工作。
explicit LoggerAdapter(OldLogger& old) : old_(old) {} 引用的初始化规律是: T& 名字 = 某个已有对象; // 或 T& 名字(某个已有对象);括号左边是成员名old_,括号里是用来初始化它的表达式old。构造时用参数初始化成员
因为成员是引用 OldLogger&,必须用初始化列表绑定
old_ 是成员,old 是参数
等价于在说:
构造时执行:OldLogger& old_ = old;(当然实际只能写在初始化列表里,不能事后赋值)
于是 old_ 和参数 old(也就是 main 里的那个对象)指向同一块对象。
old_(old)是 C++ 的成员初始化写法,对引用成员来说就等于「old_别名到参数old」,所以能绑上。
#include <string> #include <cstdio> // ---------- 被适配者:已有老类(不能 / 不想改)---------- class OldLogger { public: void write(const char* msg) { std::printf("[OLD] %s\n", msg); } }; // ---------- 目标接口:新系统希望这样用 ---------- class ILogger { public: virtual ~ILogger() = default; virtual void info(const std::string& msg) = 0; }; // ---------- 适配器:对外像 ILogger,对内用 OldLogger ---------- class LoggerAdapter : public ILogger { OldLogger& old_; // 组合:持有被适配对象 public: explicit LoggerAdapter(OldLogger& old) : old_(old) {} void info(const std::string& msg) override { // 接口转换:string → const char* old_.write(msg.c_str()); } }; // ---------- 客户端:只认识 ILogger ---------- void report(ILogger& log) { log.info("system start"); } int main() { OldLogger old; LoggerAdapter adapter(old); // 转接头 report(adapter); // 输出: [OLD] system start }