2010-01-18 13 views
11

Tengo dos clases¿Cómo se usa el constructor no predeterminado para un miembro?

class a { 
    public: 
     a(int i); 
}; 

class b { 
    public: 
     b(); //Gives me an error here, because it tries to find constructor a::a() 
     a aInstance; 
} 

¿Cómo puedo conseguirlo de manera que se crea una instancia AINSTANCE con un (int i) en lugar de tratar de buscar un constructor por defecto? Básicamente, quiero controlar la llamada de un constructor desde el constructor de b.

+0

Me doy cuenta de que esto es un ejemplo, y no un código real, pero solo por el bien de ~~ ser una calidad de código pedante ~~, generalmente no es una buena idea hacer campos 'públicos'. Claro, hay algunos casos de uso, y no es "universalmente malo", pero antes de hacerlo, asegúrese de que haya una razón más allá de "podría simplificar parte de mi código" ("simplifica mucho mi código" es una razón perfectamente aceptable , sin embargo) –

Respuesta

20

es necesario llamar a un (int) de forma explícita en la lista de inicialización del constructor:

b() : aInstance(3) {} 

donde 3 es el valor inicial desea utilizar. Aunque podría ser cualquier int. Ver comentarios para notas importantes sobre orden y otras advertencias.

+0

Muchas gracias. Pensé que era solo para llamar a los constructores de clase padre. –

+1

Sí, también puede usarlo para inicializar miembros. –

+0

En algunos casos, debe inicializar miembros (referencias, por ejemplo), y así es como lo hace. –

3

Utilizar una lista de inicialización:

b::b() : aInstance(1) {} 
0

sólo tiene que utilizar un constructor que se define así:

class b { 
public: 
    b() 
    : aInstance(5) 
    {} 
    a aInstance; 
}; 
+1

Esto no es válido C++. –

+1

Con una variable miembro, esto solo funcionará si la variable es una 'const' estática, como en' static const int x (3); ' –

+0

Debo notar que no estoy pasando una constante al constructor, sino otra miembro de b. Cuando intento hacer a aInstance (c); lo interpreta como una definición de función. –

-2

Creo que se debe utilizar un puntero a 'a' como:

class b { 
public: 
    b() : aInstance(new a(5)) {} 
    a *aInstance; 
}; 

De esta manera tendrá un comportamiento definido. Por supuesto, tendrá que liberar * una instancia en el destructor.

+1

La asignación de montón no se prefiere mucho a la asignación de pila. A su código le falta un constructor de copias, un operador de asignación y un destructor. – GManNickG

+1

Estoy de acuerdo. Fui demasiado rápido con mi comentario, especialmente porque una instancia es solo un objeto pequeño. Estaba pensando en situaciones de la vida real donde los objetos podrían ser más grandes, donde podría haber una inicialización lenta, etc. Supongo que he estado haciendo demasiado C# y Java últimamente, donde casi todo se hace por referencia;) –

Cuestiones relacionadas