Reflexão e Introspecção em C++: Como fazer o código ver a si mesmo

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

O que é reflexão e introspecção em C++ e para que servem?

\n\n

Imagine que você está escrevendo um motor de jogo complexo ou um framework para processamento de dados. Em algum momento, você precisa entender: "O que é esse objeto, afinal? Quais métodos ele tem? Ele tem um campo name?"

\n\n

Em linguagens como Python ou Java, isso é feito em uma linha — elas têm reflexão completa (a capacidade do programa de estudar e modificar sua própria estrutura durante a execução). Já em C++, é mais complicado. C++ é uma linguagem com tipagem estática forte, e "de fábrica" quase não há reflexão. Mas existe a introspecção — a capacidade limitada de obter informações sobre tipos em tempo de execução.

\n\n

Neste artigo, vamos abordar:

\n
    \n
  • A diferença entre reflexão e introspecção;
  • \n
  • Como funciona o RTTI (Run-Time Type Information);
  • \n
  • Como usar typeid e dynamic_cast;
  • \n
  • Como emular reflexão com templates e macros;
  • \n
  • Alternativas modernas (C++20/23) e bibliotecas.
  • \n
\n\n

Pronto para mergulhar no "espelho" do C++? Vamos lá!

\n\n

Introspecção vs Reflexão: qual a diferença?

\n\n

Antes de escrever código, vamos esclarecer os pontos.

\n\n
    \n
  • Introspecção — é a capacidade do programa de "olhar para si mesmo" e obter informações sobre tipos, mas sem modificar a estrutura do programa. Exemplo: "Descobrir o nome da classe de um objeto". Isso existe em C++ através do RTTI.
  • \n
  • Reflexão — é a introspecção + a capacidade de criar objetos dinamicamente, chamar métodos, modificar campos. Isso não existe no padrão C++ (ainda).
  • \n
\n\n

Em C++, usamos o termo "reflexão" mais como um objetivo, e "introspecção" como a ferramenta disponível. Mas não se assuste: mesmo com meios limitados, é possível fazer coisas incríveis.

\n\n

RTTI (Run-Time Type Information) — a base da introspecção em C++

\n\n

RTTI é um mecanismo que permite determinar o tipo de um objeto durante a execução. Ele é ativado por padrão (embora em alguns sistemas embarcados seja desativado com a flag -fno-rtti).

\n\n

Os principais componentes do RTTI:

\n
    \n
  • typeid — operador que retorna std::type_info;
  • \n
  • dynamic_cast — conversão segura de tipos polimórficos.
  • \n
\n\n

Exemplo 1: Usando typeid

\n\n
#include <iostream>\n#include <typeinfo>\n\nclass Base { virtual void foo() {} };\nclass Derived : public Base {};\n\nint main() {\n    Base* b = new Derived();\n    std::cout << "Tipo do objeto: " << typeid(*b).name() << std::endl;\n    delete b;\n    return 0;\n}
\n\n

Saída (depende do compilador): class Derived ou 7Derived (nome distorcido).

\n\n

Observe: typeid funciona apenas com classes polimórficas (que tenham pelo menos um método virtual). Se remover o virtual, você obterá o tipo do ponteiro, não o objeto real.

\n\n

Exemplo 2: dynamic_cast — conversão segura

\n\n
#include <iostream>\n\nclass Animal { public: virtual ~Animal() = default; };\nclass Dog : public Animal { public: void bark() { std::cout << "Woof!\\n"; } };\nclass Cat : public Animal { public: void meow() { std::cout << "Meow!\\n"; } };\n\nvoid makeSound(Animal* a) {\n    if (Dog* dog = dynamic_cast<Dog*>(a)) {\n        dog->bark();\n    } else if (Cat* cat = dynamic_cast<Cat*>(a)) {\n        cat->meow();\n    } else {\n        std::cout << "Animal desconhecido\\n";\n    }\n}\n\nint main() {\n    Animal* pets[] = { new Dog(), new Cat(), new Animal() };\n    for (auto p : pets) makeSound(p);\n    // Não esquecer de deletar!\n    for (auto p : pets) delete p;\n    return 0;\n}
\n\n

Este é um exemplo clássico de introspecção: não sabemos qual objeto chegou, mas m

Blogs

Book Recommendations