网站首页> 文章专栏> 模板不仅仅是模板,它还能解耦
在很多人眼里的模板就是用于泛型编程的场景,甚至有些讨厌它,可能很多人还不知道它还有另外一个妙用--解耦。
看这样一个场景:
class connection {
public:
void send() {
//do business
std::cout<<buf_<<"\n";
//...
}
private:
std::string buf_;
};
有这样一个对象connection,它里面有个send函数,send的逻辑比较复杂(这里省略具体逻辑),然后这部分代码刚好可以被另外一个对象A复用,于是我就把send的业务逻辑封装到另外一个helper对象中,helper对象需要访问connection对象的buf_字段,而A对象也有这样一个buf_字段,所以connection和A对象都能调用helper的send方法,从而达到复用的目的。
#include "helper.hpp"
class connection {
public:
void send() {
helper help(this);
help.send();
}
private:
friend class helper;
std::string buf_;
};
把helper设置为friend是为了让helper访问私有字段buf_。再看看helper的代码。
#include "connection.hpp"
class helper {
public:
helper(connection *conn) : buf_(conn->buf_) {}
void send() { std::cout << buf_ << "\n"; }
private:
std::string& buf_;
};
但是这个代码这样写是编译不过的,因为两个对象依赖相互引用头文件了。不管用什么方法,相互依赖总是不好的,好办法是破除这个依赖。
是时候叫出模板了!
template<typename T>
class helper {
public:
helper(T *t) : buf_(t->buf_) {}
void send() { std::cout << buf_ << "\n"; }
private:
std::string& buf_;
};
helper 不再引用connection的头文件,而是通过一个模板来泛化含有buf_的对象,它不再关心具体的对象是什么了,它只关心这个对象是否存在buf_字段。
#include "helper.hpp"
class connection {
public:
void send() {
helper help(this);
help.send();
}
private:
friend class helper<connection>;
std::string buf_;
};
#include "helper.hpp"
class A {
public:
void send() {
helper help(this);
help.send();
}
private:
friend class helper<A>;
std::string buf_;
};
低版本的编译器可能在这一行代码编译不过:
helper help(this);
因为helper是一个模板类,需要填模板参数。这时候可以使用C++17的dedution guide来消除这个模板参数:
template<typename T>
class helper {
public:
helper(T *t) : buf_(t->buf_) {}
void send() { std::cout << buf_ << "\n"; }
private:
std::string& buf_;
};
template <typename T>
helper(T *t) -> helper<T>; //dedution guide
这样connection和A就能复用同样的逻辑了,而且也不会产生相互依赖,解开了耦合。模板不仅仅是为了泛化,有时候可以用来解耦。
最后附上一首小诗:
赏梅
寒梅不似春花俏,淡淡香藏浅浅枝。
不惹蝶蜂眉黛敛,冰清玉洁自成诗。
地址: www.purecpp.cn
转载请注明出处!
purecpp
一个很酷的modern c++开源社区
purecpp社区自2015年创办以来,以“Newer is Better”为理念,相信新技术可以改变世界,一直致力于现代C++研究、应用和技术创新,期望通过现代C++的技术创新来提高企业生产力和效率。
社区坚持只发表原创技术文章,已经累计发表了一千多篇原创C++技术文章;
组织了十几场的C++沙龙和C++大会,有力地促进了国内外C++开发者之间的技术交流;
开源了十几个现代C++项目,被近百家公司所使用,有力地推动了现代C++在企业中的应用。
期待更多的C++爱好者能参与到社区C++社区的建设中来,一起为现代C++开源项目添砖加瓦,一起完善C++基础设施和生态圈。
微信公众号:purecpp, 社区邮箱: purecpp@163.com