Fácil C++

Contador RAII

Enunciado

Crie uma classe Contador que incrementa um contador global no construtor e o decrementa no destrutor. No main, crie um bloco e instancie um Contador; imprima o valor do contador dentro e fora do bloco para ver o efeito.

Requisitos

  • A classe deve ter um construtor que incrementa uma variável global int contador_global.
  • O destrutor deve decrementar contador_global.
  • Imprimir o valor dentro e fora do bloco.

Código inicial

#include <iostream>

int contador_global = 0;

class Contador {
    // TODO: implementar construtor e destrutor
};

int main() {
    // TODO: criar bloco e testar
    return 0;
}

Saída esperada

Dentro do bloco: 1
Fora do bloco: 0
Ver dica

Use std::cout para imprimir. O destrutor é chamado automaticamente ao final do bloco.

Mostrar solução
#include <iostream>

int contador_global = 0;

class Contador {
public:
    Contador() {
        ++contador_global;
        std::cout << "Contador criado\n";
    }
    ~Contador() {
        --contador_global;
        std::cout << "Contador destruido\n";
    }
};

int main() {
    {
        Contador c;
        std::cout << "Dentro do bloco: " << contador_global << '\n';
    } // c sai de escopo, destrutor chamado
    std::cout << "Fora do bloco: " << contador_global << '\n';
    return 0;
}

Passo a passo

  1. Declaramos uma variável global contador_global para rastrear quantos objetos Contador existem.
  2. No construtor, incrementamos contador_global e imprimimos uma mensagem.
  3. No destrutor, decrementamos contador_global e imprimimos outra mensagem.
  4. No main, criamos um bloco { ... } e instanciamos Contador c;.
  5. Dentro do bloco, imprimimos o valor atual de contador_global (deve ser 1).
  6. Ao final do bloco, c é destruído automaticamente, decrementando o contador.
  7. Fora do bloco, imprimimos novamente o valor (deve ser 0).

Por que funciona

O destrutor é chamado automaticamente quando o objeto sai de escopo, independentemente de como o escopo é deixado. Isso é a essência do RAII: o recurso (aqui, a contagem) é liberado no momento certo sem intervenção manual.

Erros comuns

  • Esquecer de decrementar no destrutor: o contador nunca volta a zero. Corrija adicionando --contador_global; no destrutor.
  • Criar o objeto fora de um bloco: o destrutor só será chamado no final do main, então a saída "Fora do bloco" mostraria 1. Use um bloco explícito.
  • Copiar o objeto: se a classe fosse copiável, o contador poderia ser decrementado mais vezes. Aqui não há cópia, mas em geral desabilite a cópia ou implemente corretamente.

Outra forma de resolver

Usar um std::unique_ptr com um deleter customizado, mas para um contador simples a classe manual é mais didática.

Saída esperada

Contador criado
Dentro do bloco: 1
Contador destruido
Fora do bloco: 0