2009-06-10 9 views
28

En C++, es legal para dar una implementación de una función virtual pura:¿En qué circunstancias es ventajoso dar una implementación de una función virtual pura?

class C 
{ 
public: 
    virtual int f() = 0; 
}; 

int C::f() 
{ 
    return 0; 
} 

Por qué querrías hacer esto?

pregunta relacionada: El C++ faq lite contiene un ejemplo:

class Funct { 
public: 
    virtual int doit(int x) = 0; 
    virtual ~Funct() = 0; 
}; 

inline Funct::~Funct() { } // defined even though it's pure virtual; it's faster this way; trust me 

No entiendo por qué el destructor se declaró virtual pura y luego implementado; y no entiendo el comentario por qué esto debería ser más rápido.

Respuesta

23

Los destructores declarados siempre deben implementarse ya que la implementación los llamará como parte de la destrucción de objetos derivados.

Se pueden implementar otras funciones virtuales puras si proporcionan una funcionalidad común útil pero siempre necesitan ser especializadas. En el caso, las implementaciones de clases normalmente derivados harán una llamada explícita a la implementación base:

void Derived::f() 
{ 
    Base::f(); 

    // Other Derived specific functionality 
} 

Por lo general, se hace un destructor virtual si necesita hacer una clase abstracta (es decir, evitar los casos no se deriva de ser creado) pero la clase no tiene otras funciones que son naturalmente virtuales puros. Creo que el 'confía en mí es más rápido' se refiere al hecho de que debido a que los destructores llamados como parte de la limpieza de objetos derivados no necesitan usar un mecanismo de búsqueda vtable, se puede aprovechar la implementación en línea, a diferencia de las llamadas a funciones virtuales típicas .

4

Si tiene una funcionalidad tan común que la clase derivada puede utilizar. Pero necesitan hacer otro trabajo como ... bueno.

Así que la clase derivada implementa la función virtual y pide la versión de base subyacente:

class X: public C 
{ 
    public: 
     virtual int f() 
     { 
      return C::f() + 1; // I am +1 over my parent. 
     } 
}; 
0

Debido a que es considerado como mal formada para escribir:

class Funct { 
public: 
    virtual int doit(int x) = 0; 
    virtual ~Funct() = 0 {}; 
}; 

El destructor todavía se llamará si deriva de esta clase. Declarar todos los métodos puros virtuales es solo por claridad. También podría escribirlo así:

class Funct { 
public: 
    virtual int doit(int x) = 0; 
    virtual ~Funct() {}; 
}; 

La clase seguirá siendo abstracta ya que al menos un método es puramente virtual. El destructor también está todavía en línea.

2

día G,

cuanto a proporcionar una implementación por defecto para una función miembro declarado en una clase base, la única razón que se me ocurre en este momento es cuando se desea proporcionar una implementación por defecto del comportamiento como una posible opción de implementación para alguien que se está especializando en la clase base.

El autor de la clase derivada puede elegir utilizar la implementación predeterminada proporcionada por el autor de la clase base en lugar de agregar su propia implementación especializada.

Generalmente, este es el caso donde las personas se oponen a tener funciones separadas para proporcionar una interfaz y una implementación predeterminada del comportamiento, pero aún desean la separación entre la implementación predeterminada y la interfaz asociada.

Ah, acabo de ver la publicación de @Martin York, que proporciona un ejemplo.

En realidad, Scott Meyers discute esto en su libro "Effective C++". Es el Ítem 36 en la 1ra edición.

HTH

aplausos,

0

En cuanto a la velocidad del destructor virtual, esto se debe a que el destructor está definido en el archivo cpp y no en el encabezado. Tiene más que ver con el tamaño que con la velocidad. Se explica en detalle en "Diseño de software de C++ a gran escala". Lamentablemente, no puedo recordar todos los detalles, pero creo que las funciones virtuales en línea se definen varias veces en el vtable.

Hay una discusión aquí: Are inline virtual functions really a non-sense?

Cuestiones relacionadas