2011-04-25 12 views
14
class A : public B 
{ 
    ... 
} 

// case I : explicitly call the base class default constructor 
A::A() : B() 
{ 
... 
} 

// case II : don't call the base class default constructor 
A::A() // : B() 
{ 
... 
} 

¿Es el caso II igual que el caso I?C++ - ¿Debo llamar al constructor predeterminado de la clase base en la lista de inicialización?

Para mí, supongo que el constructor predeterminado de base clasa B NO se llama en el caso II.

Gracias

/// /// actualización

class B 
{ 
public: 
    B() 
    { 
     cout << "B constructor" << endl; 
    } 
}; 
class A : public B 
{ 
public: 
    A() 
    { 
     cout << "A constructor" << endl; 
    } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    A a; 
    return 0; 
} 

// salida de VS2008

B constructor 
A constructor 
Press any key to continue . . . 

Respuesta

21

El constructor de la clase base se denomina en ambos casos.

Aquí hay un link a un artículo con más información.

+0

el enlace es muy bueno :) - gracias – q0987

7

Si el constructor de la clase base no toma ningún argumento, no es necesario mencionarlo explícitamente en la lista de inicialización.

1

Cada clase que se deriva de alguna otra clase debe llamar al constructor de la clase base. Una clase derivada solo se puede construir una vez que todas las clases base 'estén completamente construidas. Entonces no importa si llama al constructor de la clase base o no. Si no llama, siempre que haya un constructor predeterminado disponible para que el compilador lo determine, se ejecutará. De lo contrario, el compilador lanzará un error.

4

Para completar la experiencia de aprendizaje y desarrollar una comprensión más profunda, puede comenzar a modificar las cosas ligeramente. Por ejemplo, ¿qué sucede cuando B no tiene un constructor predeterminado? ¿Incluso compila? Otras pequeñas modificaciones como esta proporcionarán una gran experiencia de aprendizaje.

Dicho esto, en mi experiencia por lo general es mejor hacer esto

A::A() : B() { ... } 

que

A::A() { ... } 

porque el primero es más explícito, y que te llevará a pensar sobre lo que realmente está pasando con inicialización de clase base. Es probable que evite el comportamiento oculto deletreando cosas explícitamente.

+0

Te di un más uno porque sugirió formas de mejorar la comprensión de este tema. – Krythic

+0

He dado +1 porque esto responde a la pregunta "debería ...". La mayoría de las otras respuestas son para la pregunta relacionada "debe ...". –

3

Si B no tiene un constructor declarado por el usuario, el comportamiento es diferente. Compare:

struct SimpleAggregate { 
    int a; 
    float b; 
}; 

struct ClassWrapper : SimpleAggregate { 
    ClassWrapper() : SimpleAggregate() { } 
}; 

ClassWrapper w; 

Ahora, w.a y w.b están garantizados para ser cero. Si hubiera dejado la inicialización explícita de la clase base, tendrían valores indeterminados.


Puede ser desconocido para usted que, a pesar de la sintaxis, el uso anterior de SimpleAggregate() hace no llamada al constructor por defecto, sin embargo. Simplemente valoriza la inicialización de la clase base (tenemos varias buenas respuestas aquí en Stackoverflow sobre lo que es la "inicialización de valor"), no llama al constructor predeterminado porque no hay ningún usuario declarado.

Cuestiones relacionadas