欢迎大家光临【无师自通-教程网】您的到来是我们的荣幸。本站提供photoshop教程,ps教程,flash教程,cad教程,网页制作教程,excel教程,asp教程,vb教程,3d教程,c语言教程,html教程,coreldraw教程,dreamweaver教程,java教程,3dmax教程 等各种教程为主题的内容和服务,相信您会在这里找到您所需要的东东。无师自通伴您一生-谢谢您的光临!!
网站地图 设为首页
简繁切换 加入收藏
栏目待定 留言本站
您现在的位置: 无师自通-教程网 >> 程序设计 >> C++教程 >> C进阶技术 >> 教程正文

  没有公告

教程: C 箴言:如何访问模板化基类中的名字 更多...
教程: C 箴言:如何访问模板化基类中的名字

ed C 跨越到 Template C ,inheritance(继承)会停止工作。



  为了重新启动它,我们必须以某种方式使 C 的 "don't look in templatized base classes"(不在模板基类中寻找)行为失效。有三种方法可以做到这一点。首先,你可以在调用 base class functions(基类函数)的前面加上 "this->":

template<typename Company>
class LoggingMsgSender: public MsgSender<Company> {
public:
...

void sendClearMsg(const MsgInfo& info)
{
 write "before sending" info to the log;
 this->sendClear(info); // okay, assumes that
 // sendClear will be inherited
 write "after sending" info to the log;
}
...
};
  第二,你可以使用一个 using declaration,如果你已经读过《C 箴言:避免覆盖通过继承得到的名字》,这应该是你很熟悉的一种解决方案。该文解释了 using declarations 如何将被隐藏的 base class names(基类名字)引入到一个 derived class(派生类)领域中。因此我们可以这样写 sendClearMsg:

template<typename Company>
class LoggingMsgSender: public MsgSender<Company> {
public:
 using MsgSender<Company>::sendClear; // tell compilers to assume
 ... // that sendClear is in the
 // base class
 void sendClearMsg(const MsgInfo& info)
 {
  ...
  sendClear(info); // okay, assumes that
  ... // sendClear will be inherited
 }
 ...
};
  (虽然 using declaration 在这里和《C 箴言:避免覆盖通过继承得到的名字》中都可以工作,但要解决的问题是不同的。这里的情形不是 base class names(基类名字)被 derived class names(派生类名字)隐藏,而是如果我们不告诉它去做,编译器就不会搜索 base class 领域。)

  最后一个让你的代码通过编译的办法是显式指定被调用的函数是在 base class(基类)中的:

template<typename Company>
class LoggingMsgSender: public MsgSender<Company> {
public:
...
void sendClearMsg(const MsgInfo& info)
{
 ...
 MsgSender<Company>::sendClear(info); // okay, assumes that
 ... // sendClear will be
} // inherited

...
};
  通常这是一个解决这个问题的最不合人心的方法,因为如果被调用函数是 virtual(虚拟)的,显式限定会关闭 virtual binding(虚拟绑定)行为。

  从名字可见性的观点来看,这里每一个方法都做了同样的事情:它向编译器保证任何后继的 base class template(基类模板)的 specializations(特化)都将支持 general template(通用模板)提供的 interface(接口)。所有的编译器在解析一个像 LoggingMsgSender 这样的 derived class template(派生类模板)是,这样一种保证都是必要的,但是如果保证被证实不成立,真相将在后继的编译过程中暴露。例如,如果后面的源代码中包含这些,

LoggingMsgSender<CompanyZ> zMsgSender;
MsgInfo msgData;
... // put info in msgData
zMsgSender.sendClearMsg(msgData); // error! won't compile
  对 sendClearMsg 的调用将不能编译,因为在此刻,编译器知道 base class(基类)是 template specialization(模板特化)MsgSender<CompanyZ>,它们也知道那个 class(类)没有提供 sendClearMsg 试图调用的 sendClear function(函数)。

  从根本上说,问题就是编译器是早些(当 derived class template definitions(派生类模板定义)被解析的时候)诊断对 base class members(基类成员)的非法引用,还是晚些时候(当那些 templates(模板)被特定的 template arguments(模板参数)实例化的时候)再进行。C 的方针是宁愿早诊断,而这就是为什么当那些 classes(类)被从 templates(模板)实例化的时候,它假装不知道 base classes(基类)的内容。

  Things to Remember

  ·在 derived class templates(派生类模板)中,可以经由 "this->" 前缀引用 base class templates(基类模板)中的名字,经由 using declarations,或经由一个 explicit base class qualification(显式基类限定)。


上一页  [1] [2] 

教程录入:admin    责任编辑:admin 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
     
     
     
     

    access基础知识
    免责声明!本站资料大部分来自于互联网,其版权归原作者或其他合法者所有.如内容涉及或侵犯了您的权益,请通知本人,我将尽快处理!.欢迎您的光临。
    辽ICP备07003958号
    无师自通,伴你一生-教程网