2010-05-06 9 views
5

El código siguiente se compila con gcc v4.3.3 y la clase secundaria con plantilla parece estar anulando una función virtual en el elemento primario, pero eso no rompe la regla de que no puede tener una función de plantilla virtual? ¿O está sucediendo algo más que no entiendo?Plantilla clase infantil que sobrescribe la función virtual de una clase principal

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; 
} 

Esto da salida entonces:

Base int 3
Base doble 5.5
TT Niño 3
Base doble 5.5
TT Niño 3
Base doble 5.5

como esperaba , pero no estoy seguro de por qué funciona.

Respuesta

8

Una plantilla de clase puede tener funciones miembro virtuales.

Una plantilla de función miembro no puede ser virtual. Esto es, el siguiente es válido:

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

Además, si una clase derivada tiene una plantilla de función miembro con el mismo nombre que una función virtual en una clase base, no reemplazar la función virtual. Por lo tanto, si TemplateClass::Func había sido miembro de una plantilla de función, por ejemplo,

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

no habría anulado BaseClass::Func.

+0

Veo mi confusión con clases de plantilla vs funciones de plantilla ahora. Por lo tanto, en el código anterior, TemplateClass está haciendo un Func (int) virtual en la compilación, que luego anula el Func (int) virtual de la clase principal – user334066

+0

@user: Exactly. –

2

No infringe la regla. La regla actual es 14.5.2/4:

Una plantilla de función miembro no debe ser virtual. [Ejemplo:

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