2012-06-02 50 views
3

我有一個基類與虛擬函數:強插功能僅適用於特定類型的模板

class Base 
{ 
public: 
    virtual void Function(); 
}; 

void Base::Function() 
{ 
    cout << "default version" << endl; 
} 

和派生模板類:

template <class T> class Derived : public Base 
{ 
public: 
    virtual void Function(); 
}; 

有沒有一種方法,使Function()是從基礎類爲所有類型,除了一些選擇的?因此,我要的是能夠定義,比如說一個被覆蓋的Function()intlong

void Derived<int>::Function() 
{ 
    cout << "overriden version 1" << endl; 
} 

void Derived<long>::Function() 
{ 
    cout << "overriden version 2" << endl; 
} 

,並有Function()對於所有其他類型的默認版本,沒有Function()他們明確的定義,因此的

int main() 
{ 
    Derived<int> derivedInt; 
    derivedInt.Function(); 

    Derived<long> derivedLong; 
    derivedLong.Function(); 

    Derived<double> derivedDouble; 
    derivedDouble.Function(); 
} 

輸出將

overriden version 1 
overriden version 2 
default version 

它是p ossible?

+0

寫得很好的問題。 –

回答

3

是的,專精Derived

  • 寫的通用版本沒有它(它將從Base繼承它)
  • 專門Derived覆蓋

簡單的方案,但它的工作原理。類模板

4

會員功能其實都是函數模板,這樣你就可以專注他們:

template <typename T> class Foo 
{ 
    void Function(); 
}; 

template <typename T> void Foo::Function() { /* ... */ } 

template <> void Foo<int>::Function() { /* ... */ } 
+0

如果將此應用於原始問題,則會定義非專用的'Derived :: Function()',但只需調用'Base :: Function()'。 – aschepler

1

首先解決(使用typeid運營商的)

#include <iostream> 
#include <typeinfo> 

using namespace std; 

class Base 
{ 
public: 
    virtual void Function(); 
}; 

void Base::Function() 
{ 
    cout << "default version\n"; 
} 

template<typename T> 
class Derived : Base 
{ 
public: 
    virtual void Function(); 
}; 

template<typename T> 
void Derived<T>::Function() 
{ 
    if(typeid(T) == typeid(int)) // check if T is an int 
    { 
     cout << "overriden version 1\n"; 
    } 
    else if(typeid(T) == typeid(long)) // check if T is a long int 
    { 
     cout << "overriden version 2\n"; 
    } 
    else // if T is neither an int nor a long 
    { 
     Base::Function(); // call default version 
    } 
} 

int main() 
{ 
    Derived<int> di; 
    Derived<long> dl; 
    Derived<float> df; 

    di.Function(); 
    dl.Function(); 
    df.Function(); 

    return 0; 
} 

我使用typeid運算符檢查T是否爲intlong int,如果是,則打印「o verriden版本[編號]「。如果不是,我叫Base::Function(),這將打印「默認版本」

注:使用typeid運營商則需要包含頭文件typeinfo

解決方法二(使用模板特)

// class declarations as before 

template<typename T> 
void Derived<T>::Function() 
{ 
    Base::Function(); // call default version 
} 

template<> 
void Derived<int>::Function() 
{ 
    cout << "overriden version 1\n"; 
} 

template<> 
void Derived<long>::Function() 
{ 
    cout << "overriden version 2\n"; 
} 

int main() 
{ 
    Derived<int> di; 
    Derived<long> dl; 
    Derived<float> df; 

    di.Function(); 
    dl.Function(); 
    df.Function(); 

    return 0; 
} 

在這裏,我解決你的問題與模板特。如果T是intlong int,我稱之爲專用版本。否則,我打電話給一般版本,這相當於Base::Function()

+1

IMO使用else-if-heimer's實現虛擬功能是一種倒退。 – aschepler

+0

你爲什麼這麼說? –