Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: NeLo en 16 de Octubre de 2002, 02:06:20 PM

Título: Llamada a constructor desde constructor
Publicado por: NeLo en 16 de Octubre de 2002, 02:06:20 PM
                                Tengo las siguientes clases:


class A

{

public:

   A();

   A( int i );



protected:

   int a;

};



class B : public A

{

public:

   B();

   B( int i );



protected:

   int b;

};



Y quiero que cuando se construya una instancia de la clase B con el constructor B( int i ), el constructor de la clase B llame al constructor de la clase A con el parametro i (es decir llame a A( i ) ).

¿Es posible?

Saludos.                                
Título: Llamada a constructor desde constructor
Publicado por: Frodrig en 16 de Octubre de 2002, 02:32:56 PM
                                No se si entiendo bien tu pregunta, pero es muy sencillo:





class B : public A

{

public:

 B();

 B( int i ): A(i) { }



protected:

 int b;

};





O si lo prefieres





class B : public A

{

public:

 B();

 B( int i ) {

   A::A(i);

 }



protected:

 int b;

};





Personalmente, me gusta usar un convenio que puso Javier Arevalo (Jare) hace tiempo en flipcode (http://www.flipcode.com/cgi-bin/msg.cgi?sh...orum=totd&id=-1) a la hora de acceder a la clase base (y usar un protocolo de inicializacion y finalizacion; yo he usado estas tecnicas en CrisolEngine y son fantasticas):





class B : public A

{

private:

// Tipos

// Acceso a clase base

typedef A Inherited;



public:

 B();

 B( int i ) {

   Inherited::A(i);

 }



protected:

 int b;

};





Saludos.                                
Título: Llamada a constructor desde constructor
Publicado por: NeLo en 16 de Octubre de 2002, 03:02:06 PM
                                Muchas gracias.                                
Título: ...
Publicado por: Grugnorr en 16 de Octubre de 2002, 06:55:22 PM
                                Uhm, el segundo caso NO es exactamente lo mismo, es análogo a usar lista de inicialización o asignaciones en un constructor.

Para llamar a un constructor en concreto con un parámetro, usa lo primero que ha puesto:



B(int i):A(i){}





Si haces:




B(int i)

{

A::A(i);

}



en este caso el al crear una instancia de la clase B, se llamará al constructor por defecto de A y después , en el constructor de A, se volverá a llamar a un constructor de A, el que recibe el parámetro.

En el primer caso, al crear un objeto del tipo B sucedería:

A(int i);
B(int);
/*Se llaman a estos 2 constructores*/

En el segundo caso:

A();
B(int i);
     A(int i);/*Llamado explicitamente desde B(int i)*/

Todo es mucho más claro, legible y eficiente si se acostumbra uno a usar listas de inicializadores, lo mismo para variables como para los constructores.                                
Título: Llamada a constructor desde constructor
Publicado por: NeLo en 16 de Octubre de 2002, 07:20:29 PM
                                Gracias Grugnorr por la explicación.

Saludos.                                
Título: Llamada a constructor desde constructor
Publicado por: metaxas en 17 de Octubre de 2002, 03:19:32 PM
El segundo caso, además, está mal:

class A

{

protected:

 int a;



public:

 A() { a = 0; };

 A( int i ) { a = i; };

};





class B : public A

{

protected:

 int b;



public:

 B() { b = 0; };

 B( int i ) { A::A(i); };



 int GetValue() { return a; };

};







B claseB(5);

int valor = claseB.GetValue();


y 'valor' vale 0 en vez de 5.

Cuando el segundo constructor de B hace A::A(i), lo que se está haciendo es crear un objeto temporal de A que inicializa la variable 'a' a 5 e inmediatamente después se destruye.

El constructor sobrecargado de B debería ser:

B( int i ) { this->A::A(i); };

o, ya puestos, como la variable en este caso está declarada como 'protected':

B( int i ) { this->a = i; };


Metaxas
Título: Llamada a constructor desde constructor
Publicado por: NeLo en 17 de Octubre de 2002, 03:36:57 PM
                                Bueno, sin el this, simplemente poniendo:

B( int i ) { A(i); };

también valdría.

Saludos.                                
Título: Llamada a constructor desde constructor
Publicado por: metaxas en 17 de Octubre de 2002, 04:13:18 PM
                                No, eso no compila, no puedes llamar al constructor de A sin el operador de ámbito.

Metaxas                                
Título: Llamada a constructor desde constructor
Publicado por: NeLo en 17 de Octubre de 2002, 07:33:42 PM
                                mmm... lo puse porque creía que lo tenía puesto así, pero ahora que lo he mirado, lo que tengo es:

B::B( int i ) : A( i )

Saludos.