C++: Herencia y miembros públicos con mismo nombre

Consideren este ejemplo:

#include <iostream>
#include <string>
using namespace std;
 
class Abuelo{
public:
    Abuelo() : m_AtributoJodido("Abuelo") {}
    virtual ~Abuelo(){}
 
    string m_AtributoJodido;
};
 
class Hijo: public Abuelo{
public:
    Hijo() : m_AtributoJodido("Hijo") {}
    virtual ~Hijo(){}
 
    string m_AtributoJodido;
};
 
class Nieto: public Hijo{
public:
    Nieto(){}
    virtual ~Nieto(){}
};
 
int main(){
        
      Nieto n;
      cout << "Nieto, sin desambiguar: " << n.m_AtributoJodido << endl;
      cout << "Nieto, desambiguado a Hijo: " << n.Hijo::m_AtributoJodido << endl;
      cout << "Nieto, desambiguado a Abuelo: " << n.Abuelo::m_AtributoJodido << endl;
      return 0;
}

Ignoremos momentáneamente el hecho de que hay atributos públicos (se viola el encapsulamiento). Supongamos, a efectos prácticos, que no escribimos código como este sino que nos topamos con código legacy/escrito por otro.

Lo que este código nos muestra es qué pasa cuando una clase (Nieto) hereda un atributo público (m_AtributoJodido) de su ancestro directo (Hijo), y al mismo tiempo, el ancestro del ancestro directo (Abuelo) tiene declarado un atributo público con el mismo nombre. La pregunta es... ¿Cuál de los dos hereda Nieto?

Este test, ejecutado en un compilador online muy copado para hacer pruebitas como esta, nos muestra que Nieto hereda AMBOS atributos. Si no aclaramos cuál de los dos usamos usando el operador de scope (NombreClase::atributo), se toma el del ancestro más cercano (o sea, Hijo).

De todas formas, estaría bueno correr este ejemplo en otro compilador (MSBuild, g++, mingw) y ver si ocurre lo mismo. O aún mejor, consultar el Estándar C++ para ver si el comportamiento está definido en estos casos.

Comments

Popular posts from this blog

VB.NET: Raise base class events from a derived class

Apache Kafka - I - High level architecture and concepts

Upgrading Lodash from 3.x to 4.x