本文为senlie原创。转载请保留此地址:http://blog.csdn.net/zhengsenlie

经验:可在derived class templates 内通过 "this->" 指涉 base class templates 内的成员名称,或藉由一个明确写出的 "base class 资格修饰符"完毕。

演示样例:

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);
//...
}; class CompanyZ{ //这个 class 不提供 sendCleartext 函数
public:
//...
void sendEncrypted(const std::string &msg);
//...
}; class MsgInfo {...};
template<typename Company>
class MsgSender{
public:
//...
void sendClear(const MsgInfo &info){
std::string msg;
Company c;
c.sendCleartext(msg);
}
void sendSecret(const MsgInfo &info){
//...
}
}; template<> //一个全特化的 MsgSender;它和一般 template 同样。区别仅仅在于它删掉了 sendClear
class MsgSender<CompanyZ>{
public:
//...
void sendSecret(const MsgInfo &info){...}
}; template<typename Company>
class LoggingMsgSender: public MsgSender<Company>{
//...
void sendClearMsg(const MsgInfo &info){
将”传送前“的信息写到 log
sendClear(info); //调用 base class 函数,这段码无法通过编译。由于全特化的版本号里没有 sendClear 这个函数
将”传阅后”的信息写到 log
}
//...
};

解析:C++知道 base class templates 有可能被特化。而那个特化版本号可能不提供和一般性 template 同样的接口,

因此它往往拒绝在 templatized base classes内寻找继承而来的名称





纠正1:在 base class 函数调用动作之前加上 this->

template<typename Company>
class LoggingMsgSender: public MsgSender<Company>{
//...
void sendClearMsg(const MsgInfo &info){
将”传送前“的信息写到 log
this->sendClear(info); //
将”传阅后”的信息写到 log
}
//...
};

纠正2:使用 using 声明式

template<typename Company>
class LoggingMsgSender: public MsgSender<Company>{
//...
using MsgSender<Company>::sendClear;
void sendClearMsg(const MsgInfo &info){
将”传送前“的信息写到 log
sendClear(info); //
将”传阅后”的信息写到 log
}
//...
};

纠正3:指出被调用的函数位于 base class 内

template<typename Company>
class LoggingMsgSender: public MsgSender<Company>{
//...
void sendClearMsg(const MsgInfo &info){
将”传送前“的信息写到 log
MsgSender<Company>::sendClear(info); //不太好。关闭了 "virtual 绑定行为"
将”传阅后”的信息写到 log
}
//...
};

解析:上面的每一解法做的事情都同样:对编译器承诺"base class template"的不论什么特化版本号都将支持其一般版本号所提供的接口。

但假设这个承诺未能被实践出来,编译器还是会报错的。





演示样例:

LoggingMsgSender<CompanyZ> zMsgSender;
MsgInfo msgData;
zMsgSender.sendClearMsg(msgData); //error

Effective C++ Item 43 学习处理模板化基类内的名称的更多相关文章

  1. Effective C++ -----条款43:学习处理模板化基类内的名称

    可在derived class templates内通过“this->“指涉base class templates内的成员名称,或藉由一个明白写出的”base class资格修饰符”完成.

  2. [EffectiveC++]item43:学习处理模板化基类内的名称

  3. 读书笔记_Effective_C++_条款四十三:学习处理模板化基类的名称

    背景是这样的,有两个不同的公司,然后想设计一个MessageSender,为这两个公司发送不同的消息,既支持明文发送SendClearText,也支持密文发送SendEncryptedText.一种思 ...

  4. 读书笔记 effective c++ Item 43 了解如何访问模板化基类中的名字

    1. 问题的引入——派生类不会发现模板基类中的名字 假设我们需要写一个应用,使用它可以为不同的公司发送消息.消息可以以加密或者明文(未加密)的方式被发送.如果在编译阶段我们有足够的信息来确定哪个信息会 ...

  5. 读书笔记 effective c++ Item 44 将与模板参数无关的代码抽离出来

    1. 使用模板可能导致代码膨胀 使用模板是节省时间和避免代码重用的很好的方法.你不需要手动输入20个相同的类名,每个类有15个成员函数,相反,你只需要输入一个类模板,然后让编译器来为你实例化20个特定 ...

  6. effective c++(07)之为多态基类声明virtual析构函数

    class TimeKeeper { public: TimeKeeper() ; ~TimeKepper() ; ... } ; class AtomicClock:public TimeKeepe ...

  7. Java中的io流学习(了解四大基类和基本步骤)

    Java中io流四大基类及io流操作四大基本步骤 io流:(input/output)即输入输出流.面向对象的思想之一是面向接口编程,面向父类编程,也就是多态.所以学好基类(父类)很重要. 分类 按处 ...

  8. 《effective C++》:条款07——为多态基类声明virtual析构函数

    在继承中,基类的析构函数需要定义为虚析构函数数否则: (1)当派生类对象经由一个base类指针删除时,而这个base类的析构函数不是虚函数时,其结果是未定义的. (2)这样做会导致derived类部分 ...

  9. Effective C++ 条款43

    学习处理模板化基类里的名称 本节作者编写的意图在我看来能够总结成一句话,就是"怎样定义并使用关于模板类的派生过程,怎样处理派生过程出现的编译不通过问题". 以下我们看一段说明性的代 ...

随机推荐

  1. 优客365 v2.9版本 后台存在SQL注入

    安装 打开后台登陆界面 http://localhost:9096/yk365/system/login.php 输入单引号报错 得到表名 经过跟踪后在\module\login.php文件出现错误 ...

  2. Android 打包出现jdk版本错误的问题

    Android 打包出现 jdk 版本错误的问题,本质上是 SDK 的问题,与 JDK 无关.如果 SDK 的 API 是24或者更高,就要求 jdk 1.8,我这里指定的 API 是22,所以去勾选 ...

  3. python 加密方式(MD5&sha&hashlib)

    1.MD5加密 import md5 m = md5.new() #或者m = md5.md5() m.update('123456') m.hexdigest() #或者md5.md5('12345 ...

  4. poj 2623 Sequence Median 堆的灵活运用

    I - Sequence Median Time Limit:1000MS     Memory Limit:1024KB     64bit IO Format:%I64d & %I64u ...

  5. faceNet编译问题

    1.执行align_dataset_mtcnn.py出现无法导入检测模型的问题 a.现象如下 Creating networks and loading parameters Traceback (m ...

  6. [分享]2013:Linux的黄金之年-十大杰出成就

    2013年已经过去.这一年见证了许多里程碑事件,使得2013年可以称得上是一个Linux的黄金之年.其中一些成果在FOSS和Linux世界更可以称得上是举世瞩目的成就. 1.Android的上升趋势 ...

  7. Windows下openssl安装及使用

    配置过程中需要生成一些mak文件,这些生成代码用perl脚本生成,所以要安装一个ActivePerl. 网址: http://www.activestate.com/activeperl/ 下载后直接 ...

  8. 五子棋游戏 canvas 事件 边界检测

    //有一定基础的人才能看得懂 <!doctype html><html lang="en"> <head> <meta charset=& ...

  9. git diff 打补丁

    [root@workstation2017 demo]# git diff old new >cc.diff[root@workstation2017 demo]# cat cc.diffdif ...

  10. Spring Boot中使用redis的发布/订阅模式

    原文:https://www.cnblogs.com/meetzy/p/7986956.html redis不仅是一个非常强大的非关系型数据库,它同时还拥有消息中间件的pub/sub功能,在sprin ...