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

引子:要将信息以明文或密文发送至不同的公司,当我们在编译期间(就是写代码的时候)有足够的信息决定传送至那一家公司,可以采用template的方法:

<pre name="code" class="cpp">#include <string>
using namespace std;

class CompanyA
{
public:
	void SendClearTxt(const string &msg);
	void SendEncrypted(const string &msg);

};

class CompanyB
{
public:
	void SendClearTxt(const string &msg);
	void SendEncrypted(const string &msg);

};

template<typename Company>
class MsgSender
{
public:
	void sendClear(const string &msg)
	{

		Company p;
		p.SendClearTxt("123");
	}

	void sendSecret(const string &msg)
	{
		Company p;
		p.SendEncrypted("123");
	}
};


 
上述代码可行,但是我想每次送出信息时做一些标记工作,那么自然想到derived class可以满足之,于是代码如下:
<pre name="code" class="cpp">template<typename Company>
class LoggingMsgSender : public MsgSender<Company>
{
public:
	void SendClearMsg(const string &msg)
	{
		//...一些记日志的工作代码
		sendClear("");//以明文发送出去
	}


};

 那么问题来了,如果有一个CompanyZ公司只接受加密的文本呢? 

<pre name="code" class="cpp">class CompanyZ
{
public:
	//只提供了个加密的发送方法
	void SendEncrypted(const string &msg);

};


 
那么,上面的class LoggingMsgSender::SendClearMsg中的sendClear方法就会编译失败,如果采用下面的实现的话:
<pre name="code" class="cpp">LoggingMsgSender<CompanyZ> zMsgSender;
zMsgSender.SendClearMsg("");

 
分析很简单因为
CompanyZ不支持SendEncrypted的方法,从而导致基类的函数sendClear会无法编译通过。Effective C++给出三个方法来解决:
1.见下面代码
               <pre name="code" class="cpp"> template<typename Company>
        class LoggingMsgSender : public MsgSender<Company>
        {
         public:
	      void SendClearMsg(const string &msg)
	      {
		   //...一些记日志的工作代码
		   this->sendClear("");//以明文发送出去
	      }


         };
 

 2.使用using告诉编译器假设sendClear位于base class内 
 
       <pre name="code" class="cpp"> template<typename Company>
        class LoggingMsgSender : public MsgSender<Company>
        {
         public:
               using Msgsender<Company>::sendClear;
	      void SendClearMsg(const string &msg)
	      {
		   //...一些记日志的工作代码
		   this->sendClear("");//以明文发送出去
	      }


         };

 
 
</pre><span style="white-space:pre"></span>3.明确指出位于base class内<span style="white-space:pre"><br /></span><pre name="code" class="cpp">        <pre name="code" class="cpp">template<typename Company>
        class LoggingMsgSender : public MsgSender<Company>
        {
         public:
               using Msgsender<Company>::sendClear;
	      void SendClearMsg(const string &msg)
	      {
		   //...一些记日志的工作代码
                   MsgSender<Company>::sendClear("");//以明文发送出去
} };

 
 
 
 总结:其实模板化的基类的名称,当使用模板参数定义的对象时,要注意其有可能,导致driver class的实现不正确(找不到基类的方法),这时可以采取以上三种方法来明确指出。 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值