función virtual pura con implementación

Mi entendimiento básico es que no hay implementación para una función virtual pura, sin embargo, me dijeron que podría haber implementación para la función virtual pura.

class A { public: virtual void f() = 0; }; void A::f() { cout<<"Test"<<endl; } 

¿El código está arriba?

¿Cuál es el propósito de convertirlo en una función virtual pura con una implementación?

Una función virtual pura debe implementarse 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 completo (llamando a A::f() en 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 en la cabeza es cuando hay un comportamiento por defecto más o menos razonable, pero el diseñador de la clase quiere que ese comportamiento de tipo de defecto sea invocado solo de manera explícita. También puede ser el caso en el que desee que las clases derivadas siempre realicen su propio trabajo pero también puedan invocar 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 progtwigdores de C ++, incluso a los experimentados).

Para ser claro, estás entendiendo mal = 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), tiene muy poco sentido proporcionar una definición, ya que nunca se invocará a menos que alguien lo haga explícitamente a través de Base :: Function (…) o si el El constructor de la clase base llama a la función virtual en cuestión.

La ventaja de esto es que obliga a los tipos derivados a anular el método, pero también proporciona una implementación predeterminada o aditiva.

Si tiene un código que debe ejecutar la clase derivada, pero no desea que se ejecute directamente, y desea forzarlo a que se anule.

Su código es correcto, aunque en general no se trata de 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 único 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:

 class Base { public: virtual ~Base() = 0; }; Base::~Base() {} class Derived : public Base {}; int main() { // Base b; -- compile error Derived d; } 

Tendría que dar un cuerpo a un destructor virtual puro, por ejemplo 🙂

Leer: http://cplusplus.co.il/2009/08/22/pure-virtual-destructor/

(Enlace roto, use archivo)

Si eso es correcto. En su ejemplo, las clases que se derivan de A heredan tanto la interfaz f () como una implementación predeterminada. Pero fuerza a las clases derivadas a implementar el método f () (incluso si solo es para llamar a la implementación predeterminada proporcionada por A).

Scott Meyers analiza esto en Effective C ++ (2nd Edition) Item # 36 Diferenciar entre la herencia de la interfaz y la herencia de la implementación. El número de artículo puede haber cambiado en la última edición.

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 la implementación de su clase base.

El ‘virtual void foo () = 0;’ la syntax no significa que no puedas implementar foo () en la clase actual, puedes. Tampoco significa que deba implementarlo en clases derivadas . Antes de abofetearme, observemos el Problema Diamante: (Código implícito, téngalo en cuenta).

 class A { public: virtual void foo()=0; virtual void bar(); } class B : public virtual A { public: void foo() { bar(); } } class C : public virtual A { public: void bar(); } class D : public B, public C {} int main(int argc, const char* argv[]) { A* obj = new D(); **obj->foo();** return 0; } 

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, comstackrá el comstackdor) En C ++ hay muchas lagunas.

Espero poder ayudarlo 🙂