2012-06-29 18 views
11

Estoy tratando de entender un punto aquí en C++. Si la clase A tiene un método no virtual, y la clase B, que se extiende A, anula ese método, ¿puedo crear una instancia de B y de alguna manera usar el método definido en B? ¿Hay algún punto para anular un método no virtual?¿Puedo usar un método que anule un método no virtual?

+1

Lo que describes se llama * ocultar *, no anula. Mire aquí, por ejemplo: http://stackoverflow.com/questions/2161462/c-inheritance-and-function-overriding – jrok

Respuesta

31

¿Hay algún punto para anular un método no virtual?

en realidad no son de primer orden, pero esto es el comportamiento, es decir

B* b = new B(); 
A* a = new B(); 
b->method(); //Calls B's method 
a->method(); // Calls A's method 

Por lo tanto, el tipo de puntero/referencia determina el método llamado.

¿puedo crear una instancia de B y de alguna manera usar el método definido en B?

Sí. El puntero/tipo de referencia debe ser del tipo B. (ver ejemplo anterior).

Si no se declara method ser virtual, no se puede anulación, pero se puede ocultar ella.

+0

Gran respuesta, gracias – Eyal

+1

Una "gotcha" es la situación cuando 'A' a su vez se deriva de alguna clase base (o implementa una interfaz) que declara 'método virtual()', en cuyo caso el método 'a->() 'de hecho llamará a' B.method() '... – BadCash

+0

@Chip Se le olvidó resaltar la diferencia. Esta respuesta solo está completa con el comentario de BadCashs. – ManuelSchneid3r

9

Si B hereda de A, y redefine un método definido en A, a continuación, nuevas instancias de B llamarán versión B 's. Sin embargo, si el método no es virtual, entonces no hay comportamiento polimórfico, por lo que si se hace referencia a una instancia de B como A, entonces el método será A. Por ejemplo:

struct A { 
    void foo() { std::cout << "A::foo" << std::endl; } 
}; 

struct B : public A { 
    void foo() { std::cout << "B::foo" << std::endl; } 
}; 

B b; 
b.foo(); 
A *a = &b; 
a->foo(); 

La salida del código anterior sería:

B::foo 
A::foo 

Sin embargo, si el método de foo había sido virtual, entonces B::foo habría sido impresa dos veces.

+0

¡Bien escrito! :) – niknak

2

Si una función no es virtual entonces el tipo de la variable determina que la aplicación se envía demasiado:

#include <iostream> 

using namespace std; 

struct A { 
    void f() { cout << "A" << endl; } 
}; 

struct B : public A { 
    void f() { cout << "B" << endl; } 
}; 

int main(int args, char** argv) { 

    B b; 
    A& a = b; 

    b.f(); 
    a.f(); 

    return 0; 
} 
0
  • No, no existe un mecanismo para anular un método no virtual en la clase A.
  • sí, se puede utilizar un método no virtual de la clase a en B sobrecargada usando el operador de resolución de ámbito un :: methodName
Cuestiones relacionadas