2011-06-18 36 views
11

¿Qué significa la palabra clave virtual al anular un método? No lo estoy usando y todo funciona bien.¿Qué significa la palabra clave virtual al anular un método?

¿Todos los compiladores se comportan igual en este sentido?

¿Debo usarlo o no?

+0

posible duplicado de [C++ Virtual/Pure Virtual Explicado] (http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained) –

+0

@Harald: Nop. Tema diferente – Xeo

+0

Pero estoy preguntando sobre el uso de esa palabra clave. No sobre el método virtual abstracto. – kravemir

Respuesta

11

No se puede reemplazar una función miembro sin ella.

Sólo puede ocultar uno.

struct Base { 
    void foo() {} 
}; 

struct Derived : Base { 
    void foo() {} 
}; 

Derived::foo hace no override Base::foo; simplemente esconde porque tiene el mismo nombre, de modo que la siguiente:

Derived d; 
d.foo(); 

invoca Derived::foo.

virtual permite polimorfismo tal que en realidad o funciones de mando:

struct Base { 
    virtual void foo() {} 
}; 

struct Derived : Base { 
    virtual void foo() {} // * second `virtual` is optional, but clearest 
}; 

Derived d; 
Base& b = d; 
b.foo(); 

Esto invoca Derived::foo, porque esto ahora anulacionesBase::foo — su objeto es polimórfico.

(También tiene de usar referencias o punteros para esto, debido a the slicing problem.)


  • Derived::foo no tiene que repetir la palabra clave virtual porque Base::foo ya se ha utilizado. Esto está garantizado por el estándar y puede confiar en él. Sin embargo, algunos piensan que es mejor mantener eso para mayor claridad.
+2

Sé que virtual es necesario al declarar el método que puede ser anulado. He preguntado sobre el uso de esta palabra clave cuando se reemplaza el método, no se declara. – kravemir

+1

@Miro: No sigo. Anula una función declarando otra que la anule. De cualquier manera, al menos mi párrafo final responde su pregunta. –

8

Un método virtual en la clase base se aplicará en cascada a través de la jerarquía, haciendo que cada método de subclase con la misma firma también virtual.

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

class Derived1 : public Base{ 
public: 
    virtual void foo(){} // fine, but 'virtual' is no needed 
}; 

class Derived2 : public Base{ 
public: 
    void foo(){} // also fine, implicitly 'virtual' 
}; 

le recomiendo escribir la virtual sin embargo, si a modo de documentación solamente.

5

Cuando una función es virtual, permanece virtual en toda la jerarquía, especifique o no explícitamente cada vez que sea virtual. Al reemplazar un método, utilice virtuales con el fin de ser más explícitos - ninguna otra diferencia :)

class A 
{ 
    virtual void f() 
    { 
     /*...*/ 
    }; 
}; 

class B:public A; 
{ 
    virtual void f() //same as just void f() 
    { 
     /*...*/ 
    }; 
}; 
Cuestiones relacionadas