Interfaces em C++: Como declarar e não enlouquecer

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Interfaces em C++: Guia para quem está cansado de pesquisar

\n\n

Se você já programou em Java ou C# e depois migrou para C++, certamente já se perguntou: "Onde está a palavra-chave interface?". Spoiler: ela não existe. Em C++, as interfaces são implementadas de outra forma — através de classes abstratas. E isso não é um bug, é uma feature que oferece uma flexibilidade incrível.

\n\n

No Stack Overflow, a pergunta "How do you declare an interface in C++?" acumula milhares de visualizações. Isso significa que até desenvolvedores experientes às vezes se confundem. Hoje vamos entender de uma vez por todas como declarar uma interface em C++ para que seu código seja limpo e o compilador fique satisfeito.

\n\n

O que é uma interface em C++? (Spoiler: é uma classe abstrata)

\n\n

Na POO clássica, uma interface é um contrato. A classe que implementa a interface deve fornecer a implementação de todos os seus métodos. Em C++, esse papel é desempenhado por uma classe abstrata — uma classe que contém pelo menos uma função virtual pura (pure virtual function).

\n\n

Lembre-se da regra principal:

\n
    \n
  • Interface = classe onde todos os métodos são virtuais puros.
  • \n
  • Classe abstrata = classe onde pelo menos um método é virtual puro (mas pode ter métodos comuns com implementação).
  • \n
\n\n

Para uma interface pura, usamos exatamente a primeira opção: nenhuma lógica, apenas declarações.

\n\n

Como declarar uma interface pura: sintaxe básica

\n\n

Aqui está um exemplo mínimo de interface para uma figura geométrica:

\n\n
class IShape {\npublic:\n    virtual double area() const = 0;      // Função virtual pura\n    virtual double perimeter() const = 0; // Outra\n    virtual ~IShape() {}                  // Destrutor virtual — obrigatório!\n};
\n\n

Observe o = 0 no final da declaração. Esta é a marcação mágica "virtual puro". Esse método não tem corpo (implementação) na classe base.

\n\n

Pontos-chave:

\n
    \n
  • Prefixo I no nome da classe — uma convenção não oficial para interfaces (I = Interface). Não é obrigatório usar, mas facilita a leitura do código.
  • \n
  • Destrutor virtual é obrigatório. Se você excluir um objeto através de um ponteiro para a interface, sem um destrutor virtual o comportamento será indefinido (ou seja, o programa irá falhar).
  • \n
  • Todos os métodos public — a interface deve ser acessível para chamadas externas.
  • \n
\n\n

Implementação da interface: das palavras à ação

\n\n

Agora vamos escrever uma classe que implementa nossa interface IShape. Que seja um círculo:

\n\n
class Circle : public IShape {\nprivate:\n    double radius;\npublic:\n    explicit Circle(double r) : radius(r) {}\n\n    double area() const override {\n        return 3.14159 * radius * radius;\n    }\n\n    double perimeter() const override {\n        return 2 * 3.14159 * radius;\n    }\n};
\n\n

A palavra-chave override (C++11 e posteriores) não é obrigatória, mas é altamente recomendada. Ela força o compilador a verificar se você está realmente sobrescrevendo um método virtual da classe base. Errou o nome? O compilador dirá: "Erro! Esse método não existe na interface".

\n\n

Polimorfismo em ação

\n\n

Agora a parte mais interessante — podemos trabalhar com diferentes figuras através de uma interface única:

\n\n
void printShapeInfo(const IShape& shape) {\n    std::cout << "Area: " << shape.area() << "\\n";\n    std::cout << "Perimeter: " << shape.perimeter() << "\\n";\n}\n\nint main() {\n    Circle c(5.0);\n    printShapeInfo(c); // Funciona!\n    return 0;\n}
\n\n

A função printShapeInfo recebe uma referência para IShape. Ela não se importa qual objeto foi passado — círculo, quadrado ou triângulo. Enquanto eles implementarem a interface, tudo funcionará. Isso é polimorfismo

Blogs

Book Recommendations