Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Llamada a constructor desde constructor

Iniciado por NeLo, 16 de Octubre de 2002, 02:06:20 PM

« anterior - próximo »

NeLo

                                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.                                
Drowning deep in my sea of loathing

Frodrig

                                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.                                

NeLo

                                Muchas gracias.                                
Drowning deep in my sea of loathing

Grugnorr

                                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.                                
hat the hells!

NeLo

                                Gracias Grugnorr por la explicación.

Saludos.                                
Drowning deep in my sea of loathing

metaxas

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

NeLo

                                Bueno, sin el this, simplemente poniendo:

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

también valdría.

Saludos.                                
Drowning deep in my sea of loathing

metaxas

                                No, eso no compila, no puedes llamar al constructor de A sin el operador de ámbito.

Metaxas                                

NeLo

                                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.                                
Drowning deep in my sea of loathing






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.