#include <iostream>
using namespace std;
class A {
public:
    A() { cout << "A()" << endl; }
    ~A() { cout << "~A()" << endl; }
};
class B : public A {
public:
    B() { cout << "B()" << endl; }
    ~B() { cout << "~B()" << endl; }
};
int main() {
    B obj;
}
Qual será a saída?
a) B()
b) A()
c) ~B() ~A()
d) A()
B()
~B()
~A()

Passo 1

O enunciado pede para determinar a saída (o que aparece no terminal) ao executar o programa C++ abaixo. Informações relevantes do enunciado e do código:
  • Temos duas classes: A e B, onde B herda publicamente de A.
  • A classe A tem um construtor que imprime A() e um destrutor que imprime ~A().
  • A classe B tem um construtor que imprime B() e um destrutor que imprime ~B().
  • No main é criado um objeto automático (local) de tipo B chamado obj com a linha B obj;.
  • O programa não faz mais nada além disso, então devemos considerar a criação do objeto e o término do main para saber quais mensagens são impressas e em que ordem.

Passo 2

Conceito: o que são construtores e destrutores e quando são chamados.
  • Construtor: é um método que é executado automaticamente quando um objeto é criado. Serve para inicializar o objeto. No nosso código, os construtores imprimem texto para demonstrar sua chamada.
  • Destrutor: é um método que é executado automaticamente quando um objeto é destruído (quando sai de escopo ou é deleteado). No nosso código, os destrutores imprimem texto para demonstrar sua chamada.
  • Para objetos automáticos (como obj dentro de main), o construtor é chamado no ponto de criação (linha B obj;) e o destrutor é chamado quando o objeto sai de escopo — aqui, no final da função main, antes de main terminar.

Passo 3

Conceito: ordem de chamadas em herança para construtores e destrutores.
  • Ao construir um objeto de uma classe derivada, primeiro são executados os construtores das classes base (da mais “alta” na hierarquia para a mais derivada), depois o construtor da classe mais derivada. Isso garante que a parte base do objeto esteja inicializada antes da parte derivada usar essa base.
  • Ao destruir um objeto, a ordem é inversa: primeiro é executado o destrutor da classe derivada, depois os destrutores das classes base (da mais derivada para a mais base). Isso evita que a parte derivada tente usar recursos da base já liberados.

Passo 4

Aplicando a regra de ordem ao nosso código:
  • Estamos criando um objeto do tipo B. A classe B herda de A. Então, na construção:
    1. Primeiro o construtor de A é chamado — esse imprime A().
    2. Depois o construtor de B é chamado — esse imprime B().
  • Quando main termina e obj sai do escopo, ocorre a destruição:
    1. Primeiro o destrutor de B é chamado — imprime ~B().
    2. Depois o destrutor de A é chamado — imprime ~A().

Passo 5

Sequência temporal completa das impressões:
  • Na criação do objeto (B obj;): aparece A() então B().
  • No final de main, ao destruir o objeto: aparece ~B() então ~A().

Passo 6

Pequena observação prática (para a prova): quando você vir código com herança e quiser saber a ordem de prints de construtores/destrutores, aplique a regra “construção: base → derivada” e “destruição: derivada → base”. Isso resolve a maioria dessas questões rapidamente.

Resposta

A()
B()
~B()
~A()

Exercícios relacionados