#include <iostream>
using namespace std;
class IPrintable {
public:
    virtual void print() = 0;
};
class Relatorio : public IPrintable {
public:
    void print() override { cout << "Imprimindo relatório" << endl; }
};
int main() {
    Relatorio r;
    r.print();
}
Qual é a saída?
a) Erro: interface não pode ser implementada em C++.
b) Imprimindo relatório
c)Nada é impresso.

Passo 1

O enunciado mostra um programa em C++ e pergunta qual é a saída entre três opções:
a) Erro: interface não pode ser implementada em C++.
b) Imprimindo relatório
c) Nada é impresso.
Informações relevantes dadas no código:
  • Há uma classe chamada IPrintable com a linha virtual void print() = 0;.
  • Há uma classe Relatorio que herda de IPrintable e declara void print() override { cout << "Imprimindo relatório" << endl; }.
  • No main() é criado um objeto Relatorio r; e chamado r.print();.
  • O código usa cout e endl (com using namespace std;).

Passo 2

O que significa virtual void print() = 0; dentro de IPrintable?
  • A sintaxe = 0 numa função virtual indica que a função é “pura” (pure virtual). Em C++ isso torna a classe contendo-a uma classe abstrata.
  • Uma classe abstrata não pode ser instanciada diretamente (ou seja, não dá para fazer IPrintable obj;).
  • Mesmo sendo abstrata, a classe pode servir como base para outras classes que forneçam implementações concretas dessas funções puras.
Explicando com calma e sem jargão: pensar em IPrintable como uma “lista de promessas” — ela diz que qualquer classe que a implemente deve ter um método print(). Mas sozinha ela não tem implementação desse método.

Passo 3

O que faz Relatorio : public IPrintable com void print() override { ... }?
  • Relatorio está herdando de IPrintable. Ao fornecer void print() override, Relatorio está cumprindo a “promessa” e dando uma implementação concreta para print.
  • O especificador override é uma proteção do compilador: indica que a função pretende sobrescrever uma função virtual da base; se a assinatura estiver errada o compilador avisa.
  • Quando uma classe base tem uma função pura e a classe derivada implementa essa função, a classe derivada deixa de ser abstrata — ela é concreta e pode ser instanciada.
Resumo amigável: Relatorio implementou print(), então podemos criar objetos Relatorio.

Passo 4

O que faz a linha Relatorio r; seguida de r.print(); no main()?
  • Relatorio r; cria um objeto concreto do tipo Relatorio. Não há tentativa de instanciar IPrintable, então não há problema com classe abstrata.
  • r.print(); chama o método print desse objeto. Como Relatorio tem a implementação de print, essa implementação é a que será executada.
  • Mesmo que a função seja virtual na base, aqui a chamada é direta ao objeto concreto — o mecanismo virtual garante que a versão correta (a da classe derivada) é usada.

Passo 5

O que acontece na execução do print() implementado em Relatorio?
  • Dentro de Relatorio::print() o código usa cout << "Imprimindo relatório" << endl;.
  • cout << "texto" escreve o texto entre aspas no fluxo de saída padrão (a tela), e << endl adiciona uma nova linha e faz flush do buffer.
  • Portanto, quando r.print() é executado, a mensagem literal escrita no corpo do método é enviada para a saída padrão seguida de uma nova linha.

Passo 6

Por que as outras alternativas estão incorretas?
  • Alternativa (a): incorreta porque C++ permite sim simular interfaces usando classes com funções puras; além disso aqui não há tentativa de instanciar a interface abstrata diretamente.
  • Alternativa (c): incorreta porque o método print efetivamente escreve algo em cout, então não é verdade que nada é impresso.

Resposta

b) Imprimindo relatório

Exercícios relacionados