Back
Close

Miembros Especiales de la Clase en C++ (Práctica 2)

camilocorreaUdeA
2,647 views

Constructores de la clase en C++

Un constructor es un método que se ejecuta de manera automática al instanciar un objeto de una clase. El constructor tiene como finalidad la incialización de las variables de la clase y posiblemente ejecutar algunos de los métodos de la clase. Una clase puede tener tantos constructores (sobrecargas) como el desarrollador lo estipule. La característica más sobresaliente de los constructores es que su nombre es el mismo que el de la clase, es decir, son métodos de la clase que se nombran igual que la clase, y que además no tienen valor de retorno. Las distintas sobrecargas del constructor de una clase van a depender de las distintas combinaciones de parámetros de entrada de la función. Cuando no se declara un constructor de manera explícita para una clase entonces C++ se encarga de asignar un constructor implícito por defecto a la clase. En esta sección se hará énfasis en 3 tipos de constructores: constructor por defecto, constructor parametrizado y constructor de copia.

class FooClass
{
	public:
	FooClass(/*Parámetros de entrada opcionales */); //Constructor
};

FooClass::FooClass()
{
	//Líneas de código del constructor
}

Por lo general los constructores son de acceso público ya que su uso más común y extendido es la inicialización de las variables de clase al momento de la declaración de un objeto. Sin embargo, es importante resaltar que los constructores también pueden tener acceso privado que es mayormente utilizado en ciertos patrones e idiomas especiales de diseño de software en los que se le encarga la instanciación de los objetos a otros métodos de la clase o a funciones externas amigas de la clase. A continuación se listan los 3 constructores de uso más común en C++:

  • Constructor por defecto: Es un constructor que no tiene parámetros de entrada, la inicialización de las variables se hace con valores por defecto que el programador codifica en el bloque de código del constructor.
#include<iostream>
using namespace std;
class FooClass
{
int x, y, z;
public:
FooClass(); //Constructor por defecto
void printVars();
};
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  • Constructor parametrizado: Es un constructor que tiene parámetros de entrada que se utilizan luego en la inicialización de las variables de clase.
#include<iostream>
using namespace std;
class FooClass
{
int x, y, z;
public:
FooClass(int, int, int); //Constructor parametrizado
void printVars();
};
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  • Constructor de copia: Es un constructor que tiene como parámetro de entrada una referencia a otro objeto de la misma clase, por tanto las variables del objeto que se está creando se inicializan con los valores de las variables del objeto que se pasa como parámetro. Por esa misma razón se conoce como constructor de copia, porque copia los valores de un objeto existente para incializar otro objeto. En la declaración del constructor el parámetro de entrada debe tener calificación const para evitar modificaciones en el objeto que se está copiando.
#include<iostream>
using namespace std;
class FooClass
{
int x, y, z;
public:
FooClass(int, int, int);
FooClass(const FooClass&); //Constructor de copia
void printVars();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Consideraciones adicionales acerca de los constructores

Lista de inicialización en constructores por defecto y parametrizados: C++ permite realizar la definición de los constructores por defecto y parametrizados utilizando una lista de inicialización que se basa en el uso de los operadores dos puntos : y paréntesis (). Adicionalmente, vale la pena mencionar que el constructor por defecto se puede definir implícitamente a partir del constructor parametrizado mediante el uso de valores por defecto para los parametros de entrada de dicho constructor. Observe y ejecute el ejemplo a continuación:

#include<iostream>
using namespace std;
class FooClass
{
int x, y, z;
public:
FooClass(int, int, int);
void printVars();
};
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Otra forma de definir de manera implícita un constructor por defecto puede ser obligandolo a tomar como valores para sus variables los que se le asignen a dichas variables directamente en su declaración. Para lograr esto es necesario utilizar el operador de asignación = y la palabra reservada default en la declaración del constructor por defecto. Con este procedimiento se le comunica al compilador de C++ que no se va a definir un constructor sino que se va a utilizar el constructor por defecto que implementaría por si mismo el compilador.

#include<iostream>
using namespace std;
class FooClass
{
int x = 1, y = 2, z = 3; //Valores asignados a las variables en la declaración
public:
FooClass() = default; //Obligando al constructor a tomar los valores de la declaración de las variables
FooClass(const FooClass&) = default; //Se va a utilizar el constructor por copia que implementa el compilador
void printVars();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

También existe la posibilidad de inhibir la utilización de cierto tipo de constructor, por ejemplo si en cierta aplicación el desarrollador no desea que los objetos de cierta clase sean copiados entonces puede prohibir la utilización del constructor de copia simplemente mediante el uso del operador de asignación = y la palabra reservada delete.

 class FooClass
{
	int x, y, z; 
	public:
	FooClass() = delete; //Se prohibe la utilización del constructor por defecto
	FooClass(int, int, int); //Único constructor que se puede utilizar
	FooClass(const FooClass&) = delete;  //Se prohibe la utilización del constructor por copia
	void printVars();
};

int main()
{
	FooClass obj1; // ¡Error, constructor por defecto deshabilitado!
	FooClass obj2(1,2,3); // ¡Bien, sin problema!
	FooClass obj3(obj2); // ¡Error, constructor de copia deshabilitado!
}

Con el constructor de copia y en general con constructores parametrizados se puede utilizar el operador de asignación = para declarar un objeto y realizar la inicialización. Por ejemplo:

#include<iostream>
using namespace std;
class FooClass
{
int x, y, z;
public:
FooClass(int, int, int); //Constructor parametrizado
FooClass(const FooClass&); //Constructor de copia
void printVars();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Para deshabilitar el uso del operador asignación = en la declaración e inicialización de un objeto y que dicha declaración solo deba hacerse tal y como está en la declaración del constructor mismo, entonces se usa la palabra reservada explicit en la declaración del constructor. Esta característica es muy útil cuando en la clase se va a definir una sobrecarga del operador asignación =. En la próxima sección se trata el tema de sobrecarga de operadores.

class FooClass
{
	int x, y, z;
	public:
	explicit FooClass(int, int, int); //Constructor parametrizado explícito
	explicit FooClass(const FooClass&);  //Constructor de copia explícito
	void printVars();
};

int main()
{
	FooClass fooObj1 = {111,222,333}; // ¡Error, el constructor se declaro explícito!
	FooClass fooObj2(111,222,333); // ¡Bien, así está declarado el constructor!
	FooClass fooObj3 = fooObj2; // ¡Error, el constructor se declaro explícito!
	FooClass fooObj4(fooObj2); // ¡Bien, así está declarado el constructor!
	return 0;
}

Dato importante: Cuando no se declara un constructor por defecto para una clase y en cambio sí se han declarado otros constructores (o por lo menos otro), entonces el compilador de C++ NO declarará de manera implícita ningún constructor por defecto.

class FooClass
{
	int x, y, z;
	public:
	FooClass(int, int, int); //Declaración constructor parametrizado 	
};

int main()
{
	FooClass fooObj1(111,222,333); // ¡Bien!
	FooClass fooObj2 = {111,222,333}; // ¡También está bien en este caso!
	FooClass fooObj3 ; // ¡Error, C++ ya no declara un constructor por defecto implícito!
	FooClass fooObj4(fooObj2); // ¡Bien, C++ si declara un constructor de copia implícito!
	FooClass fooObj5 = fooObj4; // ¡Está bien en este caso (C++ si declara un constructor de copia implícito)!
	return 0;
}
Practica lo que has aprendido
¡Practica lo aprendido!
La clase Constructores requiere la implementación de sus constructores.
Debe implementar los constructores por defecto, parametrizado y de copia.
Solo es necesario codificar dos constructores para tener las 3 implementaciones mencionadas anteriormente.
Los valores por defecto para la incialización de las variables de la clase son: 1, 0.112233445566 y "Texto por defecto"
La implementación debe hacerse utilizando lista de inicialización. ¡En la misma definición de la clase por supuesto!
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Create your playground on Tech.io
This playground was created on Tech.io, our hands-on, knowledge-sharing platform for developers.
Go to tech.io
codingame x discord
Join the CodinGame community on Discord to chat about puzzle contributions, challenges, streams, blog articles - all that good stuff!
JOIN US ON DISCORD
Online Participants