Médio C++

Construtor padrão e explicit

Enunciado

Crie uma classe Contador que mantém um valor inteiro. Ela deve ter:

  • Um construtor padrão que inicializa o contador com 0.
  • Um construtor explicit que recebe um valor inicial inteiro.
  • Um destrutor que não faz nada (ou apenas imprime uma mensagem).
  • Um método incrementar() que soma 1.
  • Um método getValor() que retorna o valor.

No main, crie um Contador padrão, incremente duas vezes e mostre o valor. Depois crie um Contador com valor inicial 10 usando construção explícita e mostre o valor.

Requisitos

  • A classe deve ter um construtor padrão que inicializa com 0.
  • Deve ter um construtor explicit Contador(int).
  • O método incrementar() deve somar 1 ao valor.
  • O programa deve exibir Valor padrao: 2 e Valor inicial: 10.

Código inicial

#include <iostream>

class Contador {
public:
    // TODO: construtor padrão
    // TODO: construtor explicit
    // TODO: destrutor
    void incrementar() { /* TODO */ }
    int getValor() const { /* TODO */ }
private:
    int valor_;
};

int main() {
    // TODO: criar contador padrão, incrementar 2x e mostrar
    // TODO: criar contador com valor 10 e mostrar
    return 0;
}

Saída esperada

Valor padrao: 2
Valor inicial: 10
Ver dica

O construtor padrão pode ser Contador() : valor_(0) {}. O construtor com argumento deve ser marcado com explicit para evitar conversões implícitas de int para Contador.

Mostrar solução
#include <iostream>

class Contador {
public:
    // Construtor padrão
    Contador() : valor_(0) {}

    // Construtor explícito com valor inicial
    explicit Contador(int valorInicial) : valor_(valorInicial) {}

    // Destrutor
    ~Contador() {}

    void incrementar() {
        ++valor_;
    }

    int getValor() const {
        return valor_;
    }

private:
    int valor_;
};

int main() {
    Contador c1;          // chama construtor padrão
    c1.incrementar();
    c1.incrementar();
    std::cout << "Valor padrao: " << c1.getValor() << "\n";

    Contador c2(10);      // construção explícita
    std::cout << "Valor inicial: " << c2.getValor() << "\n";

    return 0;
}

Passo a passo

  1. A classe Contador tem um membro privado valor_ do tipo int.
  2. O construtor padrão Contador() : valor_(0) {} inicializa valor_ com 0 usando lista de inicialização.
  3. O construtor explicit Contador(int valorInicial) : valor_(valorInicial) {} inicializa com o valor fornecido e é marcado como explicit para impedir conversões implícitas.
  4. O destrutor ~Contador() {} está vazio, mas é declarado para mostrar sua presença.
  5. incrementar() incrementa valor_ em 1.
  6. getValor() retorna o valor atual.
  7. No main, criamos c1 com o construtor padrão, incrementamos duas vezes e imprimimos. Depois criamos c2(10) e imprimimos.

Por que funciona

O construtor padrão permite criar objetos sem argumentos. O explicit impede que um int seja convertido automaticamente para Contador, evitando chamadas acidentais. A lista de inicialização garante que valor_ seja inicializado corretamente.

Erros comuns

  • Esquecer explicit e permitir Contador c = 5; — isso compila, mas pode ser indesejado. Com explicit, essa linha gera erro de compilação.
  • Não inicializar valor_ no construtor padrão: Contador() {} deixa o membro com valor indeterminado. Use a lista de inicialização.
  • Declarar o construtor padrão como Contador(int valor = 0) e também Contador() — ambíguo, o compilador pode reclamar.

Outra forma de resolver

Usar valores padrão nos parâmetros: explicit Contador(int valorInicial = 0) : valor_(valorInicial) {}. Isso elimina a necessidade de um construtor padrão separado, mas ainda é explícito.

Saída esperada

Valor padrao: 2
Valor inicial: 10