科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件C++箴言:如何访问模板化基类中的名字 (2)

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

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

如何访问模板化基类中的名字

作者:sixth 来源:赛迪论坛 2007年10月27日

关键字: C++ 模版 Linux

  • 评论
  • 分享微博
  • 分享邮件
 

注意 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 是一个 template parameter(模板参数),这个直到更迟一些才能被确定(当 LoggingMsgSender 被实例化的时候)。不知道 Company 是什么,就没有办法知道 class(类)MsgSender 是什么样子的。特别是,没有办法知道它是否有一个 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(对象)没有意义。为了纠正这个问题,我们可以创建一个 MsgSender 针对 CompanyZ 的特化版本:

template<> // a total specialization of
class MsgSender { // MsgSender; the same as the
public: // general template, except
... // sendCleartext is omitted
void sendSecret(const MsgInfo& info)
{ ... }
};

  注意这个 class definition(类定义)开始处的 "template <>" 语法。它表示这既不是一个 template(模板),也不是一个 standalone class(独立类)。正确的说法是,它是一个用于 template argument(模板参数)为 CompanyZ 时的 MsgSender template(模板)的 specialized version(特化版本)。这以 total template specialization(完全模板特化)闻名:template(模板)MsgSender 针对类型 CompanyZ 被特化,而且这个 specialization(特化)是 total(完全)的——只要 type parameter(类型参数)被定义成了 CompanyZ,就没有剩下能被改变的其它 template's parameters(模板参数)。
查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章