例程:
1 //针对每一个公司创建一个类 2 //该类包含发送铭文和密文的两个功能函数 3 class comA{ 4 public: 5 ... 6 void sendCleartext(const std::string& msg); 7 void sendEncrypted(const std::string& msg); 8 ... 9 }; 10 class comA{ 11 public: 12 ... 13 void sendCleartext(const std::string& msg); 14 void sendEncrypted(const std::string& msg); 15 ... 16 }; 17 //待发送的消息结构 18 class MsgInfo(){ 19 ... 20 }; 21 //发送消息的功能函数 22 template<typename com> 23 class MsgSender{ 24 public: 25 ... 26 void sendClear(const MsgInf& info){ 27 std::string msg; 28 根据info产生将要发送的消息; 29 com c; 30 c.sendCleartext(msg); 31 } 32 void sendSecret(const MsgInfo& info){ 33 ... 34 } 35 }; 36 template<typename com> 37 class LoggingMsgSender :public MsgSender<com>{ 38 public: 39 ... 40 void sendClearMsg(const MsgInfo& info){ 41 将传送前的消息写至log; 42 sendClear(info); //这里会出现编译错误 43 将传送后的消息写进log; 44 } 45 ... 46 };
上面的代码实现功能
1.不同公司的房消息方式存在差异,所以每个公司都定义了一个单独的类,在类中定义了两个特定的功能函数,发送铭文和发送密文的函数。
2.为了统一发送消息的动作,编写了一个模板类,专门处理发送消息,这样每个类只需要去特例化这个模板就能得到自己的发送消息的专属类。
3.考虑到发送类之前可能会记录一些日志信息,所以我们在上面的复杂发送消息的类的基础上加了一个派生类。派生类加入额外功能:可以在发送前记录日志信息。
我们可以看到在42行中的代码是不能通过编译的,原因如下:
1.模板类LoggingMsgSender继承自 MsgSender类,但是编译器在处理的时候可能会出现以下疑问:
1.具现化的MsgSender<com>中一定包含sendClear这个函数吗,答案是否定的,因为MsgSender<com>完全可能存在特例化版本二特例化版本中没有这个函数。
2.相当于这是一个泛化的版本,编译器不允许特例出现,所以就阻止了这种行为的发生。
那如果要实现该怎么办呢?
一个原则:需要对编译器作出承诺:base class template的任何特例化版本都支持其一般(泛化而非特化)版本提供的接口(所有的版本都有这一接口)。
方法有三:
1 this->sendClear(info); 2 3 using MsgSender<com>::sendClear; 4 5 sendClear(info); 6 7 MsgSender<com>::sendClear(info);
原文:https://www.cnblogs.com/xiongxinxzy/p/13093508.html