AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
## 条款43:学习处理模板化基类内的名称 Know how to access names in templatized base classes. 类模板继承的问题: ```cpp 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` 函数: ```cpp template<> class MsgSender<Company Z> { public: ... }; ``` class 定义式前的 `template<>` 语法象征着这既不是 template 也不是标准的 class,而是一个特化版的模板类,在 template 实参为 `CompanyZ` 时被使用。 解决类模板继承问题的办法有三个: * 第一个是在 Base class 函数调用动作之前加上 `this->` ; * 第二个是使用 using 声明式; * 第三个是明白指出被调用函数位于 base class 内; ```cpp 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); // 第三种 } }; ```