initialize - C++: Inicialización de campo heredado
c++ 11 constructor (4)
Tengo una pregunta sobre la inicialización de miembros heredados en el constructor de la clase derivada. Código de ejemplo:
class A
{
public:
int m_int;
};
class B: public A
{
public:
B():m_int(0){}
};
Este código me da la siguiente salida:
In constructor ''B::B()'': Line 10: error: class ''B'' does not have any field named ''m_int''
(ver http://codepad.org/tn1weFFP )
Estoy adivinando por qué sucede esto? m_int
debe ser miembro de B
, y la clase principal A
ya debe estar inicializada cuando ocurre la inicialización de m_int
en B
(porque los constructores principales se ejecutan antes de la inicialización de miembros de la clase heredada). ¿Dónde hay un error en mi razonamiento? ¿Qué es lo que realmente sucede en este código?
EDIT
: Soy consciente de otras posibilidades para inicializar este miembro (constructor base o asignación en constructor derivado), pero quiero entender por qué es ilegal en la forma en que lo intento. ¿Alguna característica específica del lenguaje C ++ o algo así? Por favor, señáleme un párrafo en el estándar de C ++ si es posible.
Debe crear un constructor para A (puede estar protegido de modo que solo B pueda llamarlo) que inicializa m_int tal como lo ha hecho, luego invoca :A(0)
donde tiene :m_int(0)
También m_int = 0
establecer m_int = 0
en el cuerpo del constructor de B. Es accesible (como usted describe) simplemente no está disponible en la sintaxis del constructor especial.
Lo que quieres es esto:
class A{
public:
A() : m_int(0);
int m_int;
};
para que m_int
se inicialice en el lugar correcto.
Editar:
De un comentario anterior, la razón por la que el compilador se queja cuando intenta inicializar la variable m_int
en B
es que el constructor de A
ya la ha inicializado. Es decir, no puede reinicializar algo, solo reasignar. Por lo tanto, puede reasignar, como lo dijo Ben Jackson, o puede inicializar en el lugar adecuado.
Para construir una instancia de la clase B
, primero debe crear una instancia de la clase A
Durante esa instanciación m_int
se inicializa. Es después de esa intialización que se llama al constructor de b
, por lo que no puede reinicializar m_int
. Si ese es su objetivo, entonces puede implementar un constructor para A
que tome un int y luego llamar a eso en la lista de inicialización de B
:
class A
{
public:
A(int x): m_int(x) {}
int m_int;
};
class B: public A
{
public:
B(): A(2) {}
};
haga un constructor en A y use B (): A (2) {} en lugar de B (): m_int (0) {} está funcionando.