网站首页> 文章专栏> 模板不仅仅是模板,它还能解耦
模板不仅仅是模板,它还能解耦
编辑时间:2024-01-10 13:36:35 作者:qicosmos 0条评论

在很多人眼里的模板就是用于泛型编程的场景,甚至有些讨厌它,可能很多人还不知道它还有另外一个妙用--解耦。

看这样一个场景:

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就能复用同样的逻辑了,而且也不会产生相互依赖,解开了耦合。模板不仅仅是为了泛化,有时候可以用来解耦。

最后附上一首小诗:

赏梅

寒梅不似春花俏,淡淡香藏浅浅枝。

不惹蝶蜂眉黛敛,冰清玉洁自成诗。


    出自:purecpp.cn

    地址: www.purecpp.cn

    转载请注明出处!


来说两句吧
登录才能发表评论。
最新评论
Absolutely

purecpp

一个很酷的modern c++开源社区


[社区开源项目列表,点击前往]


purecpp社区自2015年创办以来,以“Newer is Better”为理念,相信新技术可以改变世界,一直致力于现代C++研究、应用和技术创新,期望通过现代C++的技术创新来提高企业生产力和效率。


社区坚持只发表原创技术文章,已经累计发表了一千多篇原创C++技术文章;


组织了十几场的C++沙龙和C++大会,有力地促进了国内外C++开发者之间的技术交流;


开源了十几个现代C++项目,被近百家公司所使用,有力地推动了现代C++在企业中的应用。


期待更多的C++爱好者能参与到社区C++社区的建设中来,一起为现代C++开源项目添砖加瓦,一起完善C++基础设施和生态圈。


微信公众号:purecpp, 社区邮箱: purecpp@163.com


友情链接