Herencia en C++: public, private, protected y rendimiento

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

¿Qué se esconde detrás de los modificadores de herencia en C++?

\n\n

Imagina que eres un arquitecto. Tienes un plano de "edificio" (clase base) y quieres construir tres "casas" diferentes (clases derivadas). Una casa será una copia exacta con entrada pública (public), la segunda con un patio interior cerrado (private), y la tercera con acceso solo para familiares y amigos (protected). En C++, así es como funcionan los modificadores de herencia. Pero, ¿afecta esta elección a la velocidad del programa? Spoiler: sí y no. Analicemos cómo no dispararse en el pie y, de paso, optimizar el código.

\n\n

Esta pregunta es una de las más populares en Stack Overflow (decenas de miles de visitas), y con razón. Los principiantes a menudo confunden el nivel de acceso a los miembros de la clase con el tipo de herencia. Y los desarrolladores experimentados saben: la elección correcta de la herencia puede ahorrar horas de depuración e incluso acelerar un poco el programa. Hoy en pythonlib.ru cerramos este tema de una vez por todas.

\n\n

El triángulo de la herencia: public, private, protected

\n\n

Para empezar, lo básico. Imagina que tenemos una clase base Animal:

\n\n
class Animal {\npublic:\n    void eat() { /* ... */ }\nprotected:\n    int age;\nprivate:\n    std::string secretDNA;\n};
\n\n

Ahora veamos cómo los tres tipos de herencia cambian el acceso a estos miembros en la clase derivada Dog.

\n\n

1. Herencia Public — «tal cual»

\n

El tipo más común e intuitivo. Todos los niveles de acceso permanecen sin cambios:

\n
    \n
  • public → public (accesible para todos)
  • \n
  • protected → protected (accesible para los herederos)
  • \n
  • private → inaccesible (permanece en la clase base)
  • \n
\n

Úsalo cuando quieras expresar la relación "Dog IS-A Animal". Es la POO clásica.

\n\n

2. Herencia Protected — «solo para los nuestros»

\n

Todos los miembros public de la clase base se vuelven protected en la derivada:

\n
    \n
  • public → protected
  • \n
  • protected → protected
  • \n
  • private → inaccesible
  • \n
\n

Se necesita cuando quieres ocultar los detalles de implementación del mundo exterior, pero permitir el acceso a los "nietos". Por ejemplo, la biblioteca Boost usa activamente la herencia protected para mecanismos internos.

\n\n

3. Herencia Private — «mío y solo mío»

\n

El modo más estricto. Todos los miembros public y protected se vuelven private:

\n
    \n
  • public → private
  • \n
  • protected → private
  • \n
  • private → inaccesible
  • \n
\n

Esta es la relación "Dog está implementado A TRAVÉS DE Animal". A menudo se usa en lugar de la composición para optimizar (más sobre esto abajo).

\n\n

Rendimiento: ¿dónde está el truco?

\n\n

Y ahora, a la pregunta principal e intrigante: ¿afecta el tipo de herencia al rendimiento? En resumen: directamente no, pero indirectamente sí, y mucho.

\n\n

Mito: la herencia private es más rápida que public

\n

Algunos piensan que la herencia private "elimina comprobaciones innecesarias". Esto es falso. Los modificadores de acceso (public, protected, private) son un concepto puramente de tiempo de compilación. El compilador los verifica en la etapa de compilación y genera el mismo código máquina. No hay diferencia en tiempo de ejecución.

\n\n

Realidad: optimización mediante Empty Base Optimization (EBO)

\n

Aquí es donde la herencia private realmente acelera el programa. Si la clase base no contiene datos (clase vacía), entonces con la herencia public o protected, el compilador puede (pero no está obligado) agregar un byte adicional para la alineación. Y con la herencia private, se activa la Empty Base Optimization.

Blogs

Book Recommendations