tipos resueltos relaciones programacion multiple herencia entre ejercicios clases clase abstractas abstracta c++ inheritance multiple-inheritance

resueltos - Herencia múltiple, C++ y la misma firma de método en varias súper clases



relaciones entre clases c++ (5)

El compilador marcará este tipo de situación (es decir, al intentar llamar (some instance of RoboticsEngineer).buildRobot() ) como un error.

Esto sucede porque el objeto derivado tiene una copia de ambos objetos base (una instancia de MechanicalEngineer y una instancia de ElectricalEngineer ) dentro de sí mismo y la firma del método por sí sola no es suficiente para indicar cuál usar.

Si reemplaza buildRobot en su RoboticsEngineer , podrá decir explícitamente qué método heredado usar prefijando el nombre de la clase, por ejemplo:

void RoboticsEngineer::buildRobot() { ElectricalEngineer::buildRobot() }

Por la misma moneda, puedes "forzar" al compilador a usar una versión u otra de buildRobot con el nombre de la clase:

(some instance of RoboticsEngineer).ElectricalEngineer::buildRobot();

En este caso, se llamará a la implementación del método ElectricalEngineer , sin ambigüedad.

Se da un caso especial cuando tiene una clase base de Engineer tanto para MechanicalEngineer como para ElectricalEngineer y especifica que la herencia sea virtual en ambos casos. Cuando se usa virtual , el objeto derivado no contiene dos instancias de Engineer , pero el compilador se asegura de que solo haya una de ellas. Esto se vería así:

class Engineer { void buildRobot(); }; class MechanicalEngineer: public virtual Engineer { }; class ElectricalEngineer: public virtual Engineer { };

En este caso,

(some instance of RoboticsEngineer).buildRobot();

Se resolverá sin ambigüedades. Lo mismo es cierto si buildRobot se declara virtual y se invalida en una de las dos clases derivadas. De todos modos, si ambas clases derivadas (ElectricalEngineer y MechanicalEngineer) anulan a buildRobot , entonces la ambigüedad surge una vez más y el compilador marcará el intento de llamar (some instance of RoboticsEngineer).buildRobot(); como un error

No tengo experiencia en C ++, y provengo de un entorno Java. Últimamente, en una entrevista me preguntaron por qué Java no permitía la herencia múltiple y la respuesta fue bastante fácil. Sin embargo, todavía siento curiosidad por cómo C ++ se ocupa de eso, ya que le permite heredar de más de una clase.

Específicamente, digamos que hay una clase llamada MechanicalEngineer y otra llamada ElectricalEngineer . Ambos tienen un método llamado buildRobot() .

¿Qué sucede si hacemos un RoboticsEngineer tercera clase, que hereda de ambos y no invalida ese método, y usted solo llama:

(some instance of RoboticsEngineer).buildRobot()

¿Se lanzará una excepción o se usará el método de una de las superclases? Si es así, ¿cómo sabe el compilador qué clase usar?


El compilador se quejará de este tipo de situación.

En tal caso, c ++ sugiere crear una interfaz con una función buildRobot () del método "virtual puro". MechanicalEngineer y EletricalEnginner heredarán la Interfaz y anularán la función buildRoboot ().

Cuando creas el objeto RoboticsEnginner y llamas a la función buildRobot (), se llamará a la función de la interfaz.


No hay nada acerca de la herencia de clases múltiples que permita esto. Java produce el mismo problema con las interfaces.

public interface A { public void doStuff(); } public interface B { public void doStuff(); } public class C implements A, B {}

La respuesta simple es que el compilador arroja un error en él.


No lo maneja. Es ambiguo error C2385: ambiguous access of ''functionName''

El compilador es lo suficientemente inteligente como para saber que no debería adivinar su significado.
Para que el programa se compile, debe decirle al compilador que:
A. Sabes que es un problema problemático.
B. Dile a qué te refieres exactamente.

Para hacer esto, necesita decirle explícitamente al compilador qué método está solicitando:

RoboticsEngineer myRobot; myRobot.ElectricalEngineer::buildRobot();


struct MecEngineer { void buildRobot() { /* .... */ } }; struct EleEngineer { void buildRobot() { /* .... */ } }; struct RoboticsEngineer : MecEngineer, EleEngineer { };

Ahora cuando lo hagas,

robEngObject -> buildRobot() ;

Dicha llamada no se puede resolver y es ambigua porque ambos subobjetos tienen una función miembro con la misma firma y el compilador no sabe a cuál llamar. En tal situación, necesita mencionarlo explícitamente usando :: operator o usando static_cast .

static_cast<MecEngineer*> (robEngObject) -> buildRobot() ;