2010-05-06 83 views
5

下面的代碼使用gcc v4.3.3進行編譯,並且模板化的子類似乎正在覆蓋父代中的虛函數,但是並沒有打破您不能擁有的規則虛擬模板功能?或者是我不明白的其他事情?模板子類覆蓋父類的虛函數

class BaseClass 
{ 
public: 
    virtual void Func(int var) 
    { 
    std::cout<<"Base int "<<var<<std::endl; 
    } 

    virtual void Func(double var) 
    { 
    std::cout<<"Base double "<<var<<std::endl; 
    } 
}; 

template <class TT> 
class TemplateClass : public BaseClass 
{ 
public: 
    using BaseClass::Func; 
    virtual void Func(TT var) 
    { 
    std::cout<<"Child TT "<<var<<std::endl; 
    } 
}; 

int main(int argc, char **argv) 
{ 
    BaseClass a; 
    TemplateClass<int> b; 
    BaseClass *c = new TemplateClass<int>; 

    int intVar = 3; 
    double doubleVar = 5.5; 

    a.Func(intVar); 
    a.Func(doubleVar); 
    b.Func(intVar); 
    b.Func(doubleVar); 
    c->Func(intVar); 
    c->Func(doubleVar); 
    delete c; 
} 

這然後輸出:

基地INT 3
基雙5.5
兒童TT 3
基雙5.5
兒童TT 3
基雙5.5

如我希望,但我不確定它爲什麼起作用。

回答

8

類模板可能具有虛擬成員函數。

成員函數模板不能是虛擬的。也就是說,下面是無效:

class C 
{ 
public: 
    template <typename T> 
    virtual void f(); 
}; 

此外,如果一個派生類具有相同的名稱作爲基類,虛函數成員函數模板,它不重寫虛函數。所以,如果TemplateClass::Func過一個成員函數模板,例如,

template <typename T> 
void Func(T var) { /* ... */ } 

它不會覆蓋BaseClass::Func

+0

我現在看到我對模板類與模板函數的混淆。因此,在上面的代碼中,TemplateClass 正在編譯時創建一個虛擬的Func(int),然後覆蓋父類的虛函數(int) – user334066 2010-05-06 17:13:41

+0

@user:完全正確。 – 2010-05-06 17:24:49

2

它不違反規則。實際的規則是14.5.2/4:

成員函數模板不應該是虛擬的。 [例如:

template <class T> struct AA { 
    template <class C> virtual void g(C); // error 
    virtual void f(); // OK 
};