快速业务通道

C++箴言:如何访问模板化基类中的名字

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30
假设我们要写一个应用程序,它可以把消息传送到几个不同的公司去。消息既可以以加密方式也可以以明文(不加密)的方式传送。如果我们有足够的信息在编译期间确定哪个消息将要发送给哪个公司,我们就可以用一个 template-based(模板基)来解决问题:
class CompanyA {
public:
 ...
 void sendCleartext(const std::string& msg);
 void sendEncrypted(const std::string& msg);
 ...
};
class CompanyB {
public:
 ...
 void sendCleartext(const std::string& msg);
 void sendEncrypted(const std::string& msg);
 ...
};
... // classes for other companies
class MsgInfo { ... }; // class for holding information
// used to create a message
template<typename Company>
class MsgSender {
public:
 ... // ctors, dtor, etc.
 void sendClear(const MsgInfo& info)
 {
  std::string msg;
  create msg from info;
  Company c;
  c.sendCleartext(msg);
 }
 void sendSecret(const MsgInfo& info) // similar to sendClear, except
 { ... } // calls c.sendEncrypted
};

  这个能够很好地工作,但是假设我们有时需要在每次发送消息的时候把一些信息记录到日志中。通过一个 derived class(派生类)可以很简单地增加这个功能,下面这个似乎是一个合理的方法:
template<typename Company>
class LoggingMsgSender: public MsgSender<Company> {
public:
 ... // ctors, dtor, etc.
 void sendClearMsg(const MsgInfo& info)
 {
  write "before sending" info to the log;
  sendClear(info); // call base class function;
  // this code will not compile!
  write "after sending" info to the log;
 }
 ...
};

注意 derived class(派生类)中的 message-sending function(消息发送函数)的名字 (sendClearMsg) 与它的 base class(基类)中的那个(在那里,它被称为 sendClear)不同。这是一个好的设计,因为它避开了 hiding inherited names(隐藏继承来的名字)的问题(参见《C++箴言:避免覆盖通过继承得到的名字》)和重定义一个 inherited non-virtual function(继承来的非虚拟函数)的与生俱来的问题(参见《C++箴言:绝不重定义继承的非虚拟函数》)。但是上面的代码不能通过编译,至少在符合标准的编译器上不能。这样的编译器会抱怨 sendClear 不存在。我们可以看见 sendClear 就在 base class(基类)中,但编译器不会到那里去寻找它。我们有必要理解这是为什么。
  问题在于当编译器遇到 class template(类模板)LoggingMsgSender 的 definition(定义)时,它们不知道它从哪个 class(类)继承。当然,它是 MsgSender<Company>,但是 Company 是一个 template parameter(模板参数),这个直到更迟一些才能被确定(当 LoggingMsgSender 被实例化的时候)。不知道 Company 是什么,就没有办法知道 class(类)MsgSender<Company> 是什么样子的。特别是,没有办法知道它是否有一个 sendClear function(函数)。
  为了使问题具体化,假设我们有一个要求加密通讯的 class(类)CompanyZ:

class CompanyZ { // this class offers no
 public: // sendCleartext function
 ...
 void sendEncrypted(const std::string& msg);
 ...
};

  一般的 MsgSender template(模板)不适用于 CompanyZ,因为那个模板提供一个 sendClear function(函数)对于 CompanyZ objects(对象)

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号