原文
模板还可用来解耦
.
看这样一个场景:
类 连接 {
公:空 发送() {//干活输出<<缓冲_<<"\n";//...}
私:串 缓冲_;
};
有这样一个连接
对象,它里面有个发送
函数,发送的逻辑
比较复杂(这里省略具体逻辑
),然后刚好另外一个A对象
可复用这部分代码
,于是就把发送
的业务逻辑
封装到另外一个助手对象
中,助手对象
需要访问连接
对象的缓冲_
字段,而A对象
也有这样一个缓冲_
字段,所以连接
和A对象
都能调用助手
的发送
方法,从而达到复用
的目的.
#包含 "助手.h++"
类 连接 {
公:空 发送() {助手 帮助(本);帮助.发送();}
私:友 类 助手;//助手.串 缓冲_;
};
把助手
设置为友
,是为了让助手访问私有的缓冲_
字段.再看看助手代码
.
#包含 "连接.h++"
类 助手 {
公:助手(连接*连接):缓冲_(连接->缓冲_) {}空 发送(){输出<<缓冲_<<"\n";}
私:串& 缓冲_;
};
但是这样写该代码
是编译不过的,因为两个对象
依赖相互引用
头文件了.要去掉相互依赖
.
该叫出模板
了!
元<类 T>类 助手{
公:助手(T*t):缓冲_(t->缓冲_){}空 发送(){输出<<缓冲_<<"\n";}
私:串&缓冲_;
};
助手
不再引用连接
的头文件,而是通过模板
来泛化有缓冲_
的对象,它不再关心具体
的对象
,它只关心该对象
是否存在缓冲_
字段.
#包含 "助手.h++"
类 连接 {
公:空 发送() {助手 帮助(本);帮助.发送();}
私:友 类 助手<连接>;串 缓冲_;
};
#包含 "助手.h++"
类 A {
公:空 发送() {助手 帮助(本);帮助.发送();}
私:友 类 助手<A>;串 缓冲_;
};
低版本
编译器可能在这一行
代码编译不过:
助手 帮助(本);
因为助手
是一个需要填模板参数
的模板类
.此时可用C++17
的推导
来消除该模板参数
:
元<类 T>类 助手 {
公:助手(T*t):缓冲_(t->缓冲_){}空 发送(){输出<<缓冲_<<"\n";}
私:串&缓冲_;
};
元<类 T>
助手(T*t)->助手<T>;//推导
这样连接
和A
就能复用
相同逻辑了,而且也不会产生相互依赖
,解开了耦合
.模板还可解耦
.