Se virtual
debe implementar una función pura en un tipo derivado que se instanciará directamente, sin embargo, el tipo base aún puede definir una implementación. Una clase derivada puede llamar explícitamente a la implementación de la clase base (si los permisos de acceso lo permiten) usando un nombre de ámbito completo (llamando A::f()
a su ejemplo, si A::f()
fuera public
o protected
). Algo como:
class B : public A {
virtual void f() {
// class B doesn't have anything special to do for f()
// so we'll call A's
// note that A's declaration of f() would have to be public
// or protected to avoid a compile time problem
A::f();
}
};
El caso de uso que se me ocurre es cuando hay un comportamiento predeterminado más o menos razonable, pero el diseñador de la clase quiere que ese tipo de comportamiento predeterminado se invoque solo explícitamente. También puede ser el caso de lo que desea que las clases derivadas realicen siempre su propio trabajo, pero también puedan llamar a un conjunto común de funcionalidades.
Tenga en cuenta que, aunque está permitido por el lenguaje, no es algo que veo comúnmente utilizado (y el hecho de que se puede hacer parece sorprender a la mayoría de los programadores de C ++, incluso los experimentados).
deported
. (ya sea en un .inl o .cpp para referirse a las prácticas comunes de nomenclatura de archivos).Para ser claros, estás malinterpretando qué = 0; después de una función virtual significa.
= 0 significa que las clases derivadas deben proporcionar una implementación, no que la clase base no pueda proporcionar una implementación.
En la práctica, cuando marca una función virtual como pura (= 0), no tiene mucho sentido proporcionar una definición, porque nunca se llamará a menos que alguien lo haga explícitamente a través de Base :: Función (...) o si el El constructor de la clase base llama a la función virtual en cuestión.
fuente
La ventaja de esto es que obliga a los tipos derivados a anular el método pero también proporciona una implementación por defecto o aditiva.
fuente
Si tiene un código que debería ser ejecutado por la clase derivada, pero no desea que se ejecute directamente, y desea forzar su anulación.
Su código es correcto, aunque en general esta no es una característica de uso frecuente, y generalmente solo se ve cuando se trata de definir un destructor virtual puro; en ese caso, debe proporcionar una implementación. Lo curioso es que una vez que deriva de esa clase no necesita anular el destructor.
Por lo tanto, el uso razonable de funciones virtuales puras es especificar un destructor virtual puro como una palabra clave "no final".
El siguiente código es sorprendentemente correcto:
fuente
Tendría que darle un cuerpo a un destructor virtual puro, por ejemplo :)
Leer: http://cplusplus.co.il/2009/08/22/pure-virtual-destructor/
(Enlace roto, usar archivo)
fuente
Si eso es correcto. En su ejemplo, las clases que derivan de A heredan tanto la interfaz f () como una implementación predeterminada. Pero obliga a las clases derivadas a implementar el método f () (incluso si es solo para llamar a la implementación predeterminada proporcionada por A).
Scott Meyers analiza esto en Effective C ++ (2nd Edition) Item # 36 Diferenciar entre herencia de interfaz y herencia de implementación. El número de artículo puede haber cambiado en la última edición.
fuente
Las funciones virtuales puras con o sin cuerpo simplemente significan que los tipos derivados deben proporcionar su propia implementación.
Los cuerpos de funciones virtuales puros en la clase base son útiles si sus clases derivadas quieren llamar a su implementación de clase base.
fuente
El 'virtual void foo () = 0;' la sintaxis no significa que no pueda implementar foo () en la clase actual, sí puede. Tampoco significa que deba implementarlo en clases derivadas . Antes de abofetearme, observemos el problema del diamante: (Código implícito, eso sí).
Ahora, la invocación obj-> foo () dará como resultado B :: foo () y luego C :: bar ().
Verá ... los métodos virtuales puros no tienen que implementarse en clases derivadas (foo () no tiene implementación en la clase C - el compilador compilará) En C ++ hay muchas lagunas.
Espero poder ayudar :-)
fuente
C
en su ejemplo. Puede crear una instancia de un objeto de tipoD
porque se pone la aplicación defoo
partirB
.Un caso de uso importante de tener un método virtual puro con un cuerpo de implementación , es cuando quieres tener una clase abstracta, pero no tienes ningún método adecuado en la clase para que sea puramente virtual. En este caso, puede hacer que el destructor de la clase sea virtual puro y poner su implementación deseada (incluso un cuerpo vacío) para eso. Como ejemplo:
Esta técnica hace que la
Foo
clase sea abstracta y, como resultado, imposible crear una instancia de la clase directamente. Al mismo tiempo, no ha agregado un método virtual puro adicional para hacer que laFoo
clase sea abstracta.fuente