条款43:学习处理模板化基类内的名称
Know how to access names in templatized base classes.
类模板继承的问题:
class CompanyA {
public:
...
void sendClearText(const std::string& msg);
...
};
class CompanyB {
public:
...
void sendClearText(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);
}
};
template<typename Company>
class LoggingMsgSender: public MsgSender<Company> {
public:
...
void sendClearMsg(const MsgInfo& info) {
... // 发送前操作;
sendClear(info); // 调用基类的发送实现,编译不通过;
... // 发送后操作;
}
};
当编译器遇到 class template LoggingMsgSender
定义式时,并不知道它继承什么样的 class,因为 MsgSender<Company>
不到 class template LoggingMsgSender
被具现化出来时,是不知道 Company
的样子。也就是说编译器无法确定 sendClear
函数的具体实现,例如如果 MsgSender<Company>
存在一个特化版,它可能没有对应的 sendClear
函数:
template<>
class MsgSender<Company Z> {
public:
...
};
class 定义式前的 template<>
语法象征着这既不是 template 也不是标准的 class,而是一个特化版的模板类,在 template 实参为 CompanyZ
时被使用。
解决类模板继承问题的办法有三个:
第一个是在 Base class 函数调用动作之前加上
this->
;第二个是使用 using 声明式;
第三个是明白指出被调用函数位于 base class 内;
template<typename Company>
class LoggingMsgSender: public MsgSender<Company> {
public:
...
using MsgSender<Company>::sendClear; // 第二种
void sendClearMsg(const MsgInfo& info) {
this->sendClear(info); // 第一种
MsgSender<Company>::sendClear(info); // 第三种
}
};
Last updated
Was this helpful?