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

C++箴言:如何访问模板化基类中的名字,第1张

C++箴言:如何访问模板化基类中的名字,第2张

假设我们想编写一个应用程序,可以向几家不同的公司发送消息。消息可以以加密或明文(未加密)的形式传输。如果我们有足够的信息来确定在编译期间哪个消息将被发送到哪个公司,我们可以使用一个基于模板的(template-based)来解决问题:
Class Company A {
Public:
...
void发送明文(const STD::string & msg);
void send encrypted(const STD::string & msg);
...
};
class company b {
public:
...
void sendCleartext(const STD::string & msg);
void send encrypted(const STD::string & msg);
...
};
...//其他公司的类
类MsgInfo {...};//用于保存信息的类
//用于创建消息
模板的类
msg sender {
public:
...// ctors、dtor等。
void send clear(const MsgInfo & info)
{
STD::string msg;
根据信息创建邮件;
c公司;
c . sendcleartext(msg);
}
void send secret(const MsgInfo & info)//类似于sendClear,不同之处在于
{...} //调用c . send encrypted
};
这样做很好,但是假设我们有时需要在每次发送消息时在日志中记录一些信息。你可以简单的通过一个派生类来添加这个函数,下面似乎是一个比较合理的方法:
template
class loggings sender:public msg sender {
public:
...//导演、dtor等。
void sendClearMsg(const MsgInfo & info)
{
将“发送前”信息写入日志;
send clear(info);//调用基类函数;
//这段代码不会编译!
将“发送后”信息写入日志;
}
...
};
注意,派生类(derived class)中的消息发送函数的名称(sendClearMsg)与其基类(base class)中的名称(sendClearMsg)不同(在基类中称为sendClear)。这是一个很好的设计,因为它避免了隐藏继承名称的问题(参见C++箴言:避免覆盖继承名称)和重新定义继承的非虚函数的固有问题(参见C++箴言:永远不要重新定义继承的非虚函数)。但是上面的代码是无法编译的,至少在标准编译器上是无法编译的。这样的编译器会抱怨sendClear不存在。我们可以看到sendClear在基类里面,但是编译器不会在那里找。我们有必要了解为什么。
问题是编译器遇到类模板(class template) LoggingMsgSender的定义时,不知道它是从哪个类(class)继承的。当然是MsgSender,但是Company是一个模板参数,要等后面(LoggingMsgSender实例化的时候)才能确定。不知道什么是公司,就无从知道MsgSender是什么样的阶级。特别是没有办法知道它是否有sendClear功能(函数)。
为了使问题具体化,假设我们有一个需要加密通信的类(class)Companyz:
class Companyz {//thiclassofferno
public://sendcleartext函数
...
void发送加密的(conststd
...
};
通用的MsgSender模板(template)不适用于CompanyZ,因为对于CompanyZ对象(objects)来说,那个模板提供sendClear函数(function)是没有意义的。为了纠正这个问题,我们可以为CompanyZ创建一个MsgSender的专用版本:
template//一个
类msg sender {//msg sender;的总专用化。与
public: // general模板相同,除了
...// sendCleartext被省略
void send secret(const MsgInfo & info)
{...}
};
注意这个类定义开头的“template”语法。这意味着这既不是模板,也不是独立的类。正确的说法是,当template参数为CompanyZ时,它是MsgSender template的专用版本。这被称为总模板专门化:模板MsgSender被专门化为CompanyZ类型,这种专门化是总的——只要类型参数被定义为CompanyZ,就没有其他模板的参数可以更改。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » C++箴言:如何访问模板化基类中的名字

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情