1、问题引入
假如我们需要这样一个程序:它能够传递不同的信息到不同的公司去。所需要传递的信息分为两类:加密信息、未加密的文本信息。
针对上述需求我们可以采用template的解法:
- 首先写多个公司类,类中有发送加密信息和未加密信息的方法。
- 其次写一个信息发送类模板,其模板参数为不同的公司类。这个类用于根据模板参数向不同的公司传递信息。
2、问题升级
上述解法可以解决我们所提出的需求。但是现在,我们增加了需求。要求在发出信息后形成日志信息。我们自然而然的想法是,写一个发送信息类模板的子类模板。
这个时候,子类中的发送信息的方法应该与其父类的名称不同。这样可以避免遮掩“继承而得的名称”,也避免重新定义一个继承而得的non-virtual函数。
3、上述想法无法通过编译的原因概述
我们这个想法是合理的,但是编译的时候却通不过,这是为什么呢?
这是因为如果一个类模板B继承自一个类模板A,那么类模板B必须在在确定类模板A的模板参数的情况下,才可以使用继承而来的方法。(编译器拒绝在模板化基类中寻找继承而来的名称。)
4、C++编译为什么要这样设计呢(让上述无法通过编译)?
假如有一个公司类Z,这个公司类只允许采用加密的方法传送信息。这个时候,如果将一个公司类对象传递给类模板,模板中既有对未加密信息的传送,又有对加密信息的传送,这显然是不合理的。这个时候应该写一个特化的模板,针对特化的公司类。而C++让上述调用不能的通过编译的原因就是为了防止某些调用应该是调用特化的模板。
5、如果压根就不需要特化的模板如何解决上述问题呢?
假如说在模板中,对所有公司的方法的调用都合理。那么就没有必要让上述不能通过了。这个时候可以采取三种方法。
(1)方案一
遇到上述调用时,对于模板基类方法的调用前加this->。
(2)方案二
类模板中对所需要调用的基类方法,采用using声明式。
(3)方案三
采用全名称的调用。例如:
MsgSender<Company>::sendClrar(info);