分享

模板类的继承问题

 码农书馆 2017-12-27

   首先大家来看这段代码:

  1. class A   
  2. {  
  3. public:  
  4.     void Show()  
  5.     {  
  6.         cout << "A::Show() !!!" << endl;  
  7.     }  
  8.     void Fun()  
  9.     {  
  10.         cout << "A::Fun() !!! " << endl;  
  11.     }  
  12. };  
  13.   
  14.   
  15. class B   
  16. {  
  17. public:  
  18.     void Show()  
  19.     {  
  20.         cout << "B::Show() !!!" << endl;  
  21.     }  
  22.     void Fun()  
  23.     {  
  24.         cout << "B::Fun() !!! " << endl;  
  25.     }  
  26. };  
  27.   
  28.   
  29. class C   
  30. {  
  31. public:  
  32.     void Show()  
  33.     {  
  34.         cout << "C::Show() !!!" << endl;  
  35.     }  
  36.     void Fun()  
  37.     {  
  38.         cout << "C::Fun() !!! " << endl;  
  39.     }  
  40. };  
  41.   
  42. template<typename Com>  
  43. class Test  
  44. {  
  45. public:  
  46.     void send()  
  47.     {  
  48.         Com c;  
  49.         c.Show();  
  50.         c.Fun();  
  51.     }  
  52.     void Show()  
  53.     {  
  54.         cout << "Test::Show() !!!" << endl;  
  55.     }  
  56. };  
  57.   
  58. int main(int argc,char**argv)  
  59. {  
  60.     Test<A> t1;  
  61.     t1.send();  
  62.     t1.Show();  
  63.     cout << endl;  
  64.   
  65.     Test<B> t2;  
  66.     t2.send();  
  67.     t2.Show();  
  68.     cout << endl;  
  69.   
  70.   
  71.     Test<C> t3;  
  72.     t3.send();  
  73.     t3.Show();  
  74.     cout << endl;  
  75.   
  76.     return 0;  
  77. }  

我们先来大概分析一下这段没有实际意义的代码:

     首先定义了类A,类B,类C,这三个类都具有Show方法和Fun方法,只不过具体的实现不同。接着又定义了模板类Test。

下来我们看程序的执行结果:

     

上面的代码我们并没有使用继承,通过模板类Test的类型,使得函数的调用不同。。。

   下面我们来看如何通过继承来实现:

  1. class A   
  2. {  
  3. public:  
  4.     void Show()  
  5.     {  
  6.         cout << "A::Show() !!!" << endl;  
  7.     }  
  8.     void Fun()  
  9.     {  
  10.         cout << "A::Fun() !!! " << endl;  
  11.     }  
  12. };  
  13.   
  14.   
  15. class B   
  16. {  
  17. public:  
  18.     void Show()  
  19.     {  
  20.         cout << "B::Show() !!!" << endl;  
  21.     }  
  22.     void Fun()  
  23.     {  
  24.         cout << "B::Fun() !!! " << endl;  
  25.     }  
  26. };  
  27.   
  28.   
  29. class C   
  30. {  
  31. public:  
  32.     void Show()  
  33.     {  
  34.         cout << "C::Show() !!!" << endl;  
  35.     }  
  36.     void Fun()  
  37.     {  
  38.         cout << "C::Fun() !!! " << endl;  
  39.     }  
  40. };  
  41.   
  42. template<typename Com>  
  43. class Test  
  44. {  
  45. public:  
  46.     void send()  
  47.     {  
  48.         Com c;  
  49.         c.Show();  
  50.         c.Fun();  
  51.     }  
  52.     void Show()  
  53.     {  
  54.         cout << "Test::Show() !!!" << endl;  
  55.     }  
  56. };  
  57.   
  58. template<typename Com>  
  59. class Derived: public Test<Com>  
  60. {  
  61. public:  
  62.     //第一种方式:  
  63.     //使用using 声明式  
  64.     #if 0  
  65.     using Test<Com>::send;  
  66.     using Test<Com>::Show;  
  67.     void fun()  
  68.     {  
  69.         cout << "Derived::fun() !!!" << endl;  
  70.         Show();  
  71.         send();  
  72.     }  
  73.     #endif  
  74.   
  75.     //第二种方式  
  76.     #if 0  
  77.     void fun()  
  78.     {  
  79.         cout << "Derived::fun() !!!" << endl;  
  80.         this->Show();  
  81.         this->send();  
  82.   
  83.     }  
  84.     #endif  
  85.     //第三种方式  
  86.     #if 1  
  87.     void fun()  
  88.     {  
  89.         cout << "Derived::fun() !!!" << endl;  
  90.         Test<Com>::Show();  
  91.         Test<Com>::send();  
  92.   
  93.     }  
  94.       
  95.     #endif  
  96. };  
  97.   
  98. int main(int argc,char**argv)  
  99. {  
  100.     Derived<A> t1;  
  101.     t1.fun();  
  102.     cout << endl;  
  103.   
  104.   
  105.     Derived<B> t2;  
  106.     t2.fun();  
  107.     cout << endl;  
  108.   
  109.   
  110.     Derived<C> t3;  
  111.     t3.fun();  
  112.     cout << endl;  
  113.   
  114.     return 0;  
  115. }  

如果我们把上述Derived类中的fun函数改写成如下的形式:

  1. void fun()  
  2.     {  
  3.         cout << "Derived::fun() !!!" << endl;  
  4.         Show();  
  5.         send();  
  6.   
  7.     }  
  8.       

那么这段代码编译器是无法通过编译的。编译器则抱怨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的特化版,具体的实现如下:

  1. class A   
  2. {  
  3. public:  
  4.     void Show()  
  5.     {  
  6.         cout << "A::Show() !!!" << endl;  
  7.     }  
  8.     void Fun()  
  9.     {  
  10.         cout << "A::Fun() !!! " << endl;  
  11.     }  
  12. };  
  13.   
  14.   
  15. class B   
  16. {  
  17. public:  
  18.     void Show()  
  19.     {  
  20.         cout << "B::Show() !!!" << endl;  
  21.     }  
  22.     void Fun()  
  23.     {  
  24.         cout << "B::Fun() !!! " << endl;  
  25.     }  
  26. };  
  27.   
  28.   
  29. class C   
  30. {  
  31. public:  
  32.     void Show()  
  33.     {  
  34.         cout << "C::Show() !!!" << endl;  
  35.     }  
  36.     void Fun()  
  37.     {  
  38.         cout << "C::Fun() !!! " << endl;  
  39.     }  
  40. };  
  41.   
  42. class D  
  43. {  
  44. public:  
  45.     void Fun()  
  46.     {  
  47.         cout << "D::Fun() !!!" << endl;  
  48.     }  
  49. };  
  50.   
  51.   
  52. template<typename Com>  
  53. class Test  
  54. {  
  55. public:  
  56.     Test<Com>()  
  57.     {cout << "Test<Com>:: " << endl;}  
  58. public:  
  59.     void send()  
  60.     {  
  61.         Com c;  
  62.         c.Show();  
  63.         c.Fun();  
  64.     }  
  65.     void Show()  
  66.     {  
  67.         cout << "Test::Show() !!!" << endl;  
  68.     }  
  69.       
  70. };  
  71.   
  72.   
  73. template<>  
  74. class Test<D>  
  75. {  
  76. public:  
  77.     Test<D>()  
  78.     {cout << "Test<D>:: " << endl;}  
  79. public:  
  80.     void send()  
  81.     {  
  82.         D c;  
  83.         c.Fun();  
  84.     }  
  85.       
  86.     void Show()  
  87.     {  
  88.         cout << "Test::Show() !!!" << endl;  
  89.     }  
  90.       
  91. };  
  92.   
  93.   
  94. template<typename Com>  
  95. class Derived: public Test<Com>  
  96. {  
  97. public:  
  98.     //第一种方式:  
  99.     //使用using 声明式  
  100.     #if 0  
  101.     using Test<Com>::send;  
  102.     using Test<Com>::Show;  
  103.     void fun()  
  104.     {  
  105.         cout << "Derived::fun() !!!" << endl;  
  106.         Show();  
  107.         send();  
  108.     }  
  109.     #endif  
  110.   
  111.     //第二种方式  
  112.     #if 1  
  113.     void fun()  
  114.     {  
  115.         cout << "Derived::fun() !!!" << endl;  
  116.         this->Show();  
  117.         this->send();  
  118.   
  119.     }  
  120.     #endif  
  121.     //第三种方式  
  122.     #if 0  
  123.     void fun()  
  124.     {  
  125.         cout << "Derived::fun() !!!" << endl;  
  126.         Test<Com>::Show();  
  127.         Test<Com>::send();  
  128.   
  129.     }  
  130.       
  131.     #endif  
  132. };  
  133. int main(int argc,char**argv)  
  134. {  
  135.     Derived<A> t1;  
  136.     t1.Show();  
  137.     t1.send();  
  138.     cout << endl;  
  139.   
  140.     Derived<B> t2;  
  141.     t2.Show();  
  142.     t2.send();  
  143.     cout << endl;  
  144.   
  145.     Derived<C> t3;  
  146.     t3.Show();  
  147.     t3.send();  
  148.     cout << endl;  
  149.   
  150.     Derived<D> t4;  
  151.     t4.Show();  
  152.     t4.send();  
  153.     cout << endl;  
  154.   
  155.       
  156.     return 0;  
  157. }  


注:程序中标红的就是一个特化版的Test template,“template<>”语法象征这既不是template也不是标准class,在template实参是D时被使用。这就是所谓的模板全特化。

  我们来看程序的执行结果:

  模板类在继承时,可在derived class template内通过"this ->"指涉base class template内的成员名称,或籍由一个明白写出的“base class 资格修饰符”完成。








    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多