Effective C++ Item 43 学习处理模板化基类内的名称

本文为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 学习处理模板化基类内的名称

时间: 2024-08-24 11:41:40

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

Effective C++笔记_条款43 学习处理模板化基类内的名称

开篇就来了一个示例代码,整个这个小节就围绕这个示例代码来描述模板化基类内的名称(函数).主要是因为C++知道base class templates有可能被特化,而那个特化版本肯呢个不提供和一般性template相同的接口.因此它往往拒绝在templatized base classes(模板化基类)内寻找继承而来的名称. 1 class CompanyA { 2 public: 3 //... 4 void sendCleartext(const std::string& msg); 5 vo

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

[toc] 模板化的类作为基类时,有哪些要注意的地方.以一个例子说明,假设现在编写一个发送信息到不同公司的程序,信息要么译成密码,要么就是原始文字,在编译期间来决定哪一家公司发送至哪一家公司,采用template手法: class CompanyA{ public: void sendCleartext(const std::string& msg); void sendEncryted(const std::string& msg); -- }; class CompanyB{ publ

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

(一) 注意从 "面向对象的C++" 转向 "模板C++" 时继承可能遭遇问题 :由于基类模板可能被特化,而该特化版本可能会改变成员,因此C++拒绝在模板化基类中寻找继承而来的名称. (二) 看下面的例子: 假设将信息传送到不同的公司去,传送方式包括明文传送和密文传送,采用模板类的设计方法: class CompanyA { public: ... void sendClearText(const string& msg); void sendEncrypt

学习处理模板化基类内的名称

1.从面向对象的C++转向模板C++时继承可能遭遇问题:由于基类模板可能被特化,而该特化版本肯可能会改变成员,因此C++拒绝在模板基类中寻找继承而来的名称 2.实例:假设信息传送到不同的公司去,传送方式包括明文传送和密文传送,采用模板类的设计方法: template<typename Company> class MsgSender{ public: ... void sendClear(const MsgInfo& info){ std::string msg; ... Compan

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

1. 问题的引入——派生类不会发现模板基类中的名字 假设我们需要写一个应用,使用它可以为不同的公司发送消息.消息可以以加密或者明文(未加密)的方式被发送.如果在编译阶段我们有足够的信息来确定哪个信息会被发送到哪个公司,我们可以使用基于模板的解决方案: 1 class CompanyA { 2 public: 3 ... 4 void sendCleartext(const std::string& msg); 5 void sendEncrypted(const std::string&

C++之 模板化基类 的名称处理

在引入模板之后,我们面临一个新的问题,那就是如果继承自一个模板基类,是否跟继承一般的类有什么区别呢? 就是说,如果一个类继承自某个模板类,那么该类应该注意一些什么呢?其实,它与一般类的继承是很不一样的. 先举个简单的例子: 我们可以看到,在上述代码中,Derived类中的成员函数调用了Base类的成员函数,显然这是很合理的,因为PrintBase并没有被声明 为virtual,因此,派生类直接继承其声明与实现,可是编译器却不这么认为,编译器给出的错误是: error: there are no

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

1. 使用模板可能导致代码膨胀 使用模板是节省时间和避免代码重用的很好的方法.你不需要手动输入20个相同的类名,每个类有15个成员函数,相反,你只需要输入一个类模板,然后让编译器来为你实例化20个特定的类和300个你需要的函数.(只有在被使用的情况下类模版的成员函数才会被隐式的实例化,所以只有在300个函数被实际用到的情况下才会生成300个成员函数.)函数模板同样吸引人.你不用手动实现许多函数,你只需要实现一个函数模板,然后让编译器来做余下的事情. 然而在有些时候,如果你不小心,使用模板会导致代

Effective C++ 条款43

学习处理模板化基类里的名称 本节作者编写的意图在我看来可以总结成一句话,就是"如何定义并使用关于模板类的派生过程,如何处理派生过程出现的编译不通过问题". 下面我们看一段说明性的代码: #include<iostream> using namespace std; class object1 { public: void get(){ cout << "object1"; } void out(){ cout << "o

Effective C++ Item 44 将与参数无关的代码抽离 templates

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:Templates 生成多个 classes 和多个函数,所以任何 template 代码都不该与某个造成膨胀的 template 参数产生相依关系 因非类型模板参数(non-type template parameters) 而造成的代码膨胀,往往可消除,做法是以函数参数或 class 成员变量替换 template 参数 示例: template<typename T, std: