Implementar construtores de Classe em C++

Jinku Hu 12 outubro 2023
  1. O que são construtores e como funcionam em C++
  2. Implementar vários construtores de classes usando sobrecarga em C++
Implementar construtores de Classe em C++

Este artigo apresentará como implementar construtores de classe em C++.

O que são construtores e como funcionam em C++

Construtores são funções-membro especiais que definem como o objeto de classe deve ser inicializado. Os construtores geralmente inicializam os membros de dados da classe e são executados quando um objeto de classe é criado. Algumas características específicas das funções construtoras são que elas têm o mesmo nome da própria classe e não podem ter um tipo de retorno. Normalmente, uma classe tem vários construtores que sobrecarregam uns aos outros, mas eles devem ter um número ou tipos de parâmetros diferentes.

Observe que os construtores geralmente são especificados explicitamente pelo usuário em qualquer classe ligeiramente complexa. Ainda assim, o construtor padrão é gerado automaticamente pelo compilador quando o usuário não define nenhum construtor. O construtor padrão é geralmente aquele que não aceita argumentos e é chamado para a inicialização padrão da classe. Observe, porém, que um construtor padrão gerado pelo compilador é formalmente chamado de construtor padrão sintetizado. O último é inferido especificamente para cada classe de acordo com seus membros de dados e inicializa os membros usando o inicializador na classe ou usando o valor padrão. Portanto, construtores gerados automaticamente não são a solução universal, mas funcionam corretamente para estruturas de classes simples.

No exemplo a seguir, definimos uma classe MyClass1 com dois construtores. Observe que o primeiro não leva nenhum argumento, o que implica que é um construtor padrão, mas ainda especificamos uma palavra-chave default. O último indica ao compilador que este construtor específico deve ser o padrão. Geralmente, um compilador não gera um construtor padrão se o usuário definir qualquer construtor. Nesse caso, um usuário deve solicitar explicitamente a designação default para a função de construtor fornecida.

O segundo construtor de MyClass1 leva um único valor string como o argumento e inicializa o membro de dados name com ele. Ele imprime a string literal especial no fluxo cout apenas para tornar o momento de execução da função visível para observação. A criação do objeto m2 aciona o construtor. O objeto m1 é inicializado com o construtor padrão e, como o próprio compilador gera o último, não vemos nenhuma string impressa no fluxo 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;
}

Resultado:

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

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

Implementar vários construtores de classes usando sobrecarga em C++

MyClass1 tem o segundo membro de dados string chamado nickname. Suponha que criamos outro construtor que pega um único valor de string e o define para inicializar o nickname. Nesse caso, o compilador levantará o erro de que não podemos sobrecarregar as funções com os mesmos parâmetros. Portanto, precisamos definir outro construtor, por exemplo, escolhemos o construtor que leva duas referências de string e inicializa ambos os membros de dados. Quando o seguinte trecho de código é executado, podemos ver que o segundo construtor foi executado.

Os construtores têm características muito mais detalhadas, e apresentamos apenas os recursos principais neste artigo. Outras funções especiais contêm a palavra - construtor em seus nomes, como construtor de movimento e construtor de cópia. Estes dois fazem parte de operações especiais chamadas coletivamente de controle de cópia. Observe que os destruidores conduzem o oposto do que os construtores fazem. Ou seja, eles desalocam os membros da classe e geralmente são chamados automaticamente quando o objeto sai do escopo. Pode-se observar facilmente o comportamento da chamada do construtor-destruidor com os fragmentos de código fornecidos.

#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;
}

Resultado:

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

Artigo relacionado - C++ Class