2009-08-14 26 views
16

En C++, ¿cuál es la sobrecarga (memoria/CPU) asociada con la herencia de una clase base que no tiene funciones virtuales? ¿Es tan bueno como copiar y pegar directamente de los miembros de la clase?Sobrecarga de la herencia de C++ sin funciones virtuales

class a 
{ 
public: 
    void get(); 
protected: 
    int _px; 
} 

class b : public a 
{ 

} 

en comparación con

class a 
{ 
public: 
    void get(); 
protected: 
    int _px; 
} 

class b 
{ 
public: 
    void get(); 
protected: 
    int _px; 

} 
+5

¿De qué sirve usar la herencia (pública) si no tiene funciones virtuales? Necesitarás al menos un destructor virtual. –

+8

@Neil podría ser para la reutilización del código, evitando la reinvención de la rueda – vehomzzz

+5

En ese caso, debería usar composición, herencia privada o funciones gratuitas. –

Respuesta

23

Puede un ser ligera sobrecarga de memoria (debido al relleno) cuando se utiliza la herencia en comparación con copiar y pegar, tenga en cuenta las siguientes definiciones de clases:

struct A 
{ 
    int i; 
    char c1; 
}; 

struct B1 : A 
{ 
    char c2; 
}; 


struct B2 
{ 
    int i; 
    char c1; 
    char c2; 
}; 

sizeof (B1), probablemente será de 12, mientras que sizeof (B2) podría ser 8. Esto se debe a que la clase base A se ajusta por separado a 8 bytes y luego B1 se rellena nuevamente a 12 bytes.

+0

Ah buena observación. – jameszhao00

+0

Todas las otras respuestas son válidas, pero esto es algo que no sabía/pensaba antes. – jameszhao00

1

realidad, no sólo aumentó la memoria de la clase base. Puede leer más en here en C++ Preguntas más frecuentes

+0

Soy consciente de que hay un costo en la tabla de funciones tan pronto como se introducen las funciones virtuales. Me pregunto cómo el compilador de C++ procesa la herencia sin polimorfismo. – jameszhao00

+0

para uno, no asigna memoria para vtable, no crea un vpointer en la clase base, por lo tanto, tanto el compilador como el tiempo de ejecución tardan menos que con las funciones virtuales/dtors. ¿Qué está tratando de lograr? – vehomzzz

14

Tardará un poco más en compilarse, y no habrá sobrecarga de tiempo de ejecución adicional. Desde la perspectiva del optimizador, los métodos no virtuales son los mismos que los procedimientos: se los puede llamar utilizando solo su dirección de memoria, sin sobrecarga desde una tabla de métodos virtuales.

+0

¿Por qué tomaría más tiempo compilar? Sólo curioso. Pensé que el compilador era lo suficientemente inteligente en estos días :) – vehomzzz

+6

El aumento del tiempo será de unos pocos milisegundos, ya que el compilador tendrá que construir el árbol de herencia. No vale la pena preocuparse. –

+0

¿No quiere decir "lo mismo que los métodos no heredados"? – einpoklum

3

Si olvida herencia virtual, tener una clase base es equivalente, memoria y rendimiento, a tener un miembro de la misma clase. Exceptuando que a veces puede ser aún mejor (por ejemplo, una clase vacía tiene un tamaño de al menos uno, pero tener una clase base vacía a menudo no tiene gastos generales).

2

Si puede tener un puntero de tipo Base * que apunta a un objeto de tipo Derivado *, probablemente necesite un destructor virtual y su premisa original ya no se aplica. Si la clase derivada tiene un destructor vacío, y no tiene miembros o todos son tipos de POD, puede escaparse sin un destructor virtual, pero generalmente es mejor ir a lo seguro y hacerlo virtual desde el principio.

El compilador generará una llamada directa al código que implementa cada función miembro no virtual, por lo tanto no hay sobrecarga.

Cuestiones relacionadas