条款43:学习处理模板化基类的名称

来源:互联网 发布:社交软件的英文 编辑:程序博客网 时间:2024/05/21 12:50

先看程序:

class A{public:void funcA(){cout<<"funcA"<<endl;}};template<typename T>class UseA{public:void useAFunc(){T a;a.funcA();}};template<typename T>class DrivedUseA:public UseA<T>{public:void DrivedUseAFunc(){useAFunc();}};int main(){DrivedUseA<A> d;d.DrivedUseAFunc();return 0;}

这段程序在vc++6.0和vs2010下是没有问题的,但是在有的编译器(g++,还有一些在线编译器)上会报错。原因是因为当编译器遇见DrivedUseA时,并不知道他继承自什么类,直到基类UseA被实例化以后他才知道。而如果他不知道是通过class A实例化的,自然就不知道基类的函数具体是什么了。有3个方法可以解决这个问题:
1.在基类函数调用动作之前加上this->:this->useAFunc();
2.使用using声明:

template<typename T>class DrivedUseA:public UseA<T>{public:using UseA<T>::useAFunc;void DrivedUseAFunc(){useAFunc();}};

3.明确指出被调函数位于基类中:

template<typename T>class DrivedUseA:public UseA<T>{public:void DrivedUseAFunc(){UseA<T>::useAFunc();}}
但是第三种办法有明显的缺陷:显示指明调用基类函数会是得动态绑定不会发生。
其实,它们做的事情都是相同的:对编译器承诺基类模板的任何特化版本都将支持其泛化版本所提供的接口。
总之可以在派生类中通过this指针或者using声明来告诉派生类使用的是基类的函数。