模板类的继承问题
来源:互联网 发布:12306订票助手mac版 编辑:程序博客网 时间:2024/06/06 07:11
首先大家来看这段代码:
class A {public: void Show() { cout << "A::Show() !!!" << endl; } void Fun() { cout << "A::Fun() !!! " << endl; }};class B {public: void Show() { cout << "B::Show() !!!" << endl; } void Fun() { cout << "B::Fun() !!! " << endl; }};class C {public: void Show() { cout << "C::Show() !!!" << endl; } void Fun() { cout << "C::Fun() !!! " << endl; }};template<typename Com>class Test{public: void send() { Com c; c.Show(); c.Fun(); } void Show() { cout << "Test::Show() !!!" << endl; }};int main(int argc,char**argv){ Test<A> t1; t1.send(); t1.Show(); cout << endl; Test<B> t2; t2.send(); t2.Show(); cout << endl; Test<C> t3; t3.send(); t3.Show(); cout << endl; return 0;}
我们先来大概分析一下这段没有实际意义的代码:
首先定义了类A,类B,类C,这三个类都具有Show方法和Fun方法,只不过具体的实现不同。接着又定义了模板类Test。
下来我们看程序的执行结果:
上面的代码我们并没有使用继承,通过模板类Test的类型,使得函数的调用不同。。。
下面我们来看如何通过继承来实现:
class A {public: void Show() { cout << "A::Show() !!!" << endl; } void Fun() { cout << "A::Fun() !!! " << endl; }};class B {public: void Show() { cout << "B::Show() !!!" << endl; } void Fun() { cout << "B::Fun() !!! " << endl; }};class C {public: void Show() { cout << "C::Show() !!!" << endl; } void Fun() { cout << "C::Fun() !!! " << endl; }};template<typename Com>class Test{public: void send() { Com c; c.Show(); c.Fun(); } void Show() { cout << "Test::Show() !!!" << endl; }};template<typename Com>class Derived: public Test<Com>{public: //第一种方式: //使用using 声明式 #if 0 using Test<Com>::send; using Test<Com>::Show; void fun() { cout << "Derived::fun() !!!" << endl; Show(); send(); } #endif //第二种方式 #if 0 void fun() { cout << "Derived::fun() !!!" << endl; this->Show(); this->send(); } #endif //第三种方式 #if 1 void fun() { cout << "Derived::fun() !!!" << endl; Test<Com>::Show(); Test<Com>::send(); } #endif};int main(int argc,char**argv){ Derived<A> t1; t1.fun(); cout << endl; Derived<B> t2; t2.fun(); cout << endl; Derived<C> t3; t3.fun(); cout << endl; return 0;}
如果我们把上述Derived类中的fun函数改写成如下的形式:
void fun() { cout << "Derived::fun() !!!" << endl; Show(); send(); }
那么这段代码编译器是无法通过编译的。编译器则抱怨Show方法和send方法不存在。但是我们明明在基类Test中定义了,编译器却看不到它们,这是为什么呢?
这个问题在于,当编译器遭遇class template Derived定义式时,并不知道它继承什么样的class。当然它继承的是Test<Com>,但其中Com是个template参数,不到后来(当Derived被具体化)无法确切知道它是什么。而如果不知道Com是什么,就无法知道class Test<Com>看起来像什么-----更明确的说是没办法知道它是否有个send方法和Show方法。。
我们可以有三种方式解决这个问题:
(1)在base class函数调用动作之前加上“this ->”。
(2)使用using声明式。
(3)明确的指出被调用的函数位于base class内。
在上面的程序中也体现出来了。。。
下面我们给出程序的执行结果:
下来我们考虑这个问题,如果现在有个类D,它只有一个Fun方法,并没有Show的方法。这时我们需要为类D产生一个Test的特化版,具体的实现如下:
class A {public: void Show() { cout << "A::Show() !!!" << endl; } void Fun() { cout << "A::Fun() !!! " << endl; }};class B {public: void Show() { cout << "B::Show() !!!" << endl; } void Fun() { cout << "B::Fun() !!! " << endl; }};class C {public: void Show() { cout << "C::Show() !!!" << endl; } void Fun() { cout << "C::Fun() !!! " << endl; }};class D{public: void Fun() { cout << "D::Fun() !!!" << endl; }};template<typename Com>class Test{public: Test<Com>() {cout << "Test<Com>:: " << endl;}public: void send() { Com c; c.Show(); c.Fun(); } void Show() { cout << "Test::Show() !!!" << endl; } };template<>class Test<D>{public: Test<D>() {cout << "Test<D>:: " << endl;}public: void send() { D c; c.Fun(); } void Show() { cout << "Test::Show() !!!" << endl; } };template<typename Com>class Derived: public Test<Com>{public: //第一种方式: //使用using 声明式 #if 0 using Test<Com>::send; using Test<Com>::Show; void fun() { cout << "Derived::fun() !!!" << endl; Show(); send(); } #endif //第二种方式 #if 1 void fun() { cout << "Derived::fun() !!!" << endl; this->Show(); this->send(); } #endif //第三种方式 #if 0 void fun() { cout << "Derived::fun() !!!" << endl; Test<Com>::Show(); Test<Com>::send(); } #endif};int main(int argc,char**argv){ Derived<A> t1; t1.Show(); t1.send(); cout << endl; Derived<B> t2; t2.Show(); t2.send(); cout << endl; Derived<C> t3; t3.Show(); t3.send(); cout << endl; Derived<D> t4; t4.Show(); t4.send(); cout << endl; return 0;}
注:程序中标红的就是一个特化版的Test template,“template<>”语法象征这既不是template也不是标准class,在template实参是D时被使用。这就是所谓的模板全特化。
我们来看程序的执行结果:
模板类在继承时,可在derived class template内通过"this ->"指涉base class template内的成员名称,或籍由一个明白写出的“base class 资格修饰符”完成。
注
- 模板类的继承问题
- 模板类的继承问题
- 模板类继承问题
- 模板类的继承
- 类模板的继承
- 模板类的继承
- 模板类的继承
- 模板类的继承
- 模板类的继承
- 模板类的继承
- 模板类的继承
- 模板类的继承
- 模板类的继承
- 模板类的继承
- 模板类的继承
- 模板类的继承
- 模板类的继承
- 模板类的继承
- Spring 配置oracle数据源的两种格式
- javaweb学习总结(六)——Servlet开发(二)
- MarkDown
- 测试显示性能-基于Android M 开发者预览版
- C++第四次作业
- 模板类的继承问题
- CADisplayLink
- python 创建httpserver
- 可抢占的优先级调度算法算例:CPU利用率
- 把java程序打包成.exe
- 分解字符串
- Picasso源码解析--如何解决图片错位的问题
- android中Imagebutton实现两张图片之间的点击来回切换
- ubuntu16.04使用手札(三)——字体安装