Implementar constructores de clase en C++

Jinku Hu 12 octubre 2023
  1. Qué son los constructores y cómo funcionan en C++
  2. Implementar constructores de varias clases mediante la sobrecarga en C++
Implementar constructores de clase en C++

Este artículo presentará cómo implementar constructores de clases en C++.

Qué son los constructores y cómo funcionan en C++

Los constructores son funciones miembro especiales que definen cómo se debe inicializar el objeto de clase. Los constructores generalmente inicializan los miembros de datos de la clase y se ejecutan cuando se crea un objeto de clase. Algunas características específicas de las funciones constructoras son que tienen el mismo nombre que la clase misma y no pueden tener un tipo de retorno. Por lo general, una clase tiene varios constructores que se sobrecargan entre sí, pero deben tener un número o tipos de parámetros diferentes.

Tenga en cuenta que los constructores a menudo son especificados explícitamente por el usuario en cualquier clase ligeramente compleja. Aún así, el compilador genera automáticamente el constructor predeterminado cuando el usuario no define ningún constructor. El constructor predeterminado es generalmente el que no toma argumentos y se llama para la inicialización predeterminada de la clase. Sin embargo, tenga en cuenta que un constructor predeterminado generado por el compilador se denomina formalmente constructor predeterminado sintetizado. Este último se infiere específicamente para cada clase de acuerdo con sus miembros de datos, e inicializa los miembros usando el inicializador de la clase o usando el valor predeterminado. Por lo tanto, los constructores generados automáticamente no son la solución universal, pero funcionan correctamente para estructuras de clases simples.

En el siguiente ejemplo, definimos una clase MyClass1 con dos constructores. Observe que el primero no toma ningún argumento, lo que implica que es un constructor predeterminado, pero aún así especificamos una palabra clave default. Este último indica al compilador que este constructor específico debe ser el predeterminado. Generalmente, un compilador no genera un constructor predeterminado si el usuario define cualquier constructor. En este caso, un usuario debe solicitar explícitamente la designación default para la función de constructor dada.

El segundo constructor de MyClass1 toma un único valor de string como argumento e inicializa el miembro de datos name con él. Imprime el literal de cadena especial en la secuencia cout solo para hacer visible el momento de ejecución de la función para la observación. La creación del objeto m2 activa el constructor uno. El objeto m1 se inicializa con el constructor predeterminado, y dado que el propio compilador genera el último, no vemos ninguna cadena impresa en el flujo cout.

#include <iostream>
#include <utility>

using std::cout;
using std::endl;
using std::string;

class MyClass1 {
 private:
  string name;
  string nickname;

 public:
  MyClass1() = default;
  explicit MyClass1(string n) : name(std::move(n)) {
    cout << "Constructor 1 is called" << endl;
  };

  string getName() { return name; }

  string getNickname() { return nickname; }

  ~MyClass1() { cout << "Destructor is called" << endl; }
};

int main() {
  MyClass1 m1{};
  cout << m1.getName() << endl;
  cout << m1.getNickname() << endl;
  cout << "------------------" << endl;

  string n1("Maude");
  MyClass1 m2(n1);
  cout << m2.getName() << endl;
  cout << m2.getNickname() << endl;
  cout << "------------------" << endl;

  return EXIT_SUCCESS;
}

Producción :

------------------
Constructor 1 is called
Maude

------------------
Destructor is called
Destructor is called

Implementar constructores de varias clases mediante la sobrecarga en C++

MyClass1 tiene el segundo miembro de datos string llamado nickname. Supongamos que creamos otro constructor que toma un solo valor string y lo define para inicializar el nickname. En ese caso, el compilador generará el error de que no podemos sobrecargar las funciones con los mismos parámetros. Entonces, necesitamos definir otro constructor, por ejemplo, elegimos el constructor que toma dos referencias string e inicializa ambos miembros de datos. Cuando se ejecuta el siguiente fragmento de código, podemos ver que se ejecutó el segundo constructor.

Los constructores tienen características mucho más detalladas, y solo presentamos las características principales en este artículo. Otras funciones especiales contienen la palabra - constructor en sus nombres, como move-constructor y copy-constructor. Estos dos forman parte de operaciones especiales denominadas colectivamente control de copia. Tenga en cuenta que los destructores conducen lo contrario de lo que hacen los constructores. Es decir, desasignan los miembros de la clase y, por lo general, se les llama automáticamente cuando el objeto sale del alcance. Se puede observar fácilmente el comportamiento de la llamada al constructor-destructor con los fragmentos de código dados.

#include <iostream>
#include <utility>
#include <vector>

using std::cout;
using std::endl;
using std::string;

class MyClass1 {
 private:
  string name;
  string nickname;

 public:
  MyClass1() = default;
  explicit MyClass1(string n) : name(std::move(n)) {
    cout << "Constructor 1 is called" << endl;
  };

  // ERROR: Does not Compile
  //    MyClass1(string nk) : nickname(nk) {
  //        cout << "Constructor 3 is called" << endl;
  //    };
  MyClass1(string &n, string &nk) : name(n), nickname(nk) {
    cout << "Constructor 2 is called" << endl;
  };

  string getName() { return name; }

  string getNickname() { return nickname; }

  ~MyClass1() { cout << "Destructor is called" << endl; }
};

int main() {
  string n1("Maude");
  string n2("Bibi");

  MyClass1 m4(n1, n2);
  cout << m4.getName() << endl;
  cout << m4.getNickname() << endl;
  cout << "------------------" << endl;

  return EXIT_SUCCESS;
}

Producción :

Constructor 2 is called
Maude
Bibi
------------------
Destructor is called
Destructor is called
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artículo relacionado - C++ Class