O que está por trás dos modificadores de herança em C++?
\n\nImagine que você é um arquiteto. Você tem a planta de um "edifício" (classe base) e quer construir três "casas" diferentes (classes derivadas). Uma casa será uma cópia exata com entrada pública (public), a segunda com um pátio interno fechado (private), e a terceira com acesso apenas para família e amigos (protected). Em C++, é exatamente assim que funcionam os modificadores de herança. Mas essa escolha afeta a velocidade do programa? Spoiler: sim e não. Vamos entender como não dar um tiro no pé e, ao mesmo tempo, otimizar o código.
Esta é uma das perguntas mais populares no Stack Overflow (dezenas de milhares de visualizações), e não é à toa. Iniciantes frequentemente confundem nível de acesso aos membros da classe com tipo de herança. E desenvolvedores experientes sabem: a escolha correta da herança pode economizar horas de depuração e até acelerar um pouco o programa. Hoje, no pythonlib.ru, vamos encerrar este tópico de uma vez por todas.
\n\nO triângulo da herança: public, private, protected
\n\nPara começar, o básico. Imagine que temos uma classe base Animal:
class Animal {\npublic:\n void eat() { /* ... */ }\nprotected:\n int age;\nprivate:\n std::string secretDNA;\n};\n\nAgora, vejamos como os três tipos de herança alteram o acesso a esses membros na classe derivada Dog.
1. Herança Public — "como está"
\nO tipo mais comum e intuitivo. Todos os níveis de acesso permanecem inalterados:
\n- \n
public→public(acessível a todos) \n protected→protected(acessível a herdeiros) \n private→ inacessível (permanece na classe base) \n
Use quando quiser expressar a relação "Dog É-UM Animal". Isso é POO clássica.
\n\n2. Herança Protected — "só para os nossos"
\nTodos os membros public da classe base tornam-se protected na classe derivada:
\n- \n
public→protected\n protected→protected\n private→ inacessível \n
É útil quando você quer ocultar detalhes de implementação do mundo externo, mas permitir acesso aos "netos". Por exemplo, a biblioteca Boost usa ativamente herança protected para mecanismos internos.
\n\n3. Herança Private — "meu e só meu"
\nO modo mais restritivo. Todos os membros public e protected tornam-se private:
\n- \n
public→private\n protected→private\n private→ inacessível \n
Esta é a relação "Dog é implementado ATRAVÉS DE Animal". Frequentemente usado no lugar de composição para otimização (mais sobre isso abaixo).
\n\nDesempenho: onde está o pulo do gato?
\n\nAgora, vamos à questão principal e intrigante: o tipo de herança afeta o desempenho? Resumindo: diretamente, não; indiretamente, sim, e muito.
\n\nMito: herança private é mais rápida que public
\nAlguns pensam que a herança private "remove verificações desnecessárias". Isso não é verdade. Os modificadores de acesso (public, protected, private) são um conceito puramente de tempo de compilação. O compilador os verifica durante a compilação e gera o mesmo código de máquina. Não há diferença em tempo de execução.
Realidade: otimização através de empty base optimization (EBO)
\nAqui é onde a herança private realmente acelera o programa! Se a classe base não contém dados (classe vazia), então com herança public ou protected, o compilador pode (mas não é obrigado) adicionar um byte extra para alinhamento. Já com herança private, a Empty Base Optimization (EBO) é aplicada.