模板类的继承问题

   首先大家来看这段代码:

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。

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

      模板类的继承问题_第1张图片

上面的代码我们并没有使用继承,通过模板类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内。

   

在上面的程序中也体现出来了。。。

下面我们给出程序的执行结果:

模板类的继承问题_第2张图片

   下来我们考虑这个问题,如果现在有个类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时被使用。这就是所谓的模板全特化。

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

模板类的继承问题_第3张图片

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








你可能感兴趣的:(模板类的继承问题)