L'Héritage Multiple, C++ et la Même Méthode de Signature dans Plusieurs Super-Classes
Je n'ai pas d'expérience en C++, et je viens de Java arrière-plan. Dernièrement, on m'a demandé dans une interview sur les raisons de Java ne permettrait pas l'héritage multiple et la réponse a été assez facile. Cependant, je suis toujours curieux sur la façon dont C++ traite de la car il vous permet d'hériter de plus d'une classe.
Plus précisément, supposons qu'il existe une classe appelée MechanicalEngineer
et un autre appelé ElectricalEngineer
. Les deux ont une méthode appelée buildRobot()
.
Ce qui se passe si nous faisons une troisième classe RoboticsEngineer
, que inherets de tous les deux et ne pas surcharger cette méthode, et vous appelez simplement:
(some instance of RoboticsEngineer).buildRobot()
Sera une exception sera levée, ou la méthode à partir de l'un des super-classes seront-elles utilisées? Si oui, comment le compilateur de savoir ce qui la classe à utiliser?
- Ce qui se passe en Java si une classe possède une méthode
buildRobot
et une interface est une méthodebuildRobot
et de définir une sous-classe qui implémente l'interface? - Apparemment, c'est très bien tant que le type de retour est le même, voir ce thread.
Vous devez vous connecter pour publier un commentaire.
Le compilateur va marquer ce genre de situation (c'est à dire, la tentative d'appeler
(some instance of RoboticsEngineer).buildRobot()
) comme une erreur.Cela se produit parce que l'objet dérivé a obtenu une copie des deux objets de base (un
MechanicalEngineer
instance et unElectricalEngineer
exemple) à l'intérieur de lui-même et la signature de la méthode seule ne suffit pas de dire que l'on à utiliser.Si vous remplacez
buildRobot
dans votreRoboticsEngineer
, vous serez en mesure de dire explicitement ce qui a hérité de la méthode à utiliser en préfixant le nom de la classe, par exemple:Par la même pièce de monnaie, vous pouvez "forcer" le compilateur d'utiliser une version ou une autre de
buildRobot
en préfixant avec le nom de la classe:dans ce cas, le
ElectricalEngineer
mise en œuvre de la méthode sera appelée, sans aucune ambiguïté.Un cas particulier est donné lorsque vous avez un
Engineer
de la classe de base pour les deuxMechanicalEngineer
etElectricalEngineer
et que vous spécifiez l'héritagevirtual
dans les deux cas. Lorsquevirtual
est utilisé, la dérivée de l'objet ne contient pas de deux instances deEngineer
, mais le compilateur permet de s'assurer qu'il n'y a qu'un. Cela devrait ressembler à ceci:Dans ce cas,
sera résolu sans ambiguïtés. Le même est vrai si buildRobot est déclaré
virtual
et remplacé dans l'une des deux classes dérivées. De toute façon, si les deux classes dérivées (ElectricalEngineer et MechanicalEngineer) remplacebuildRobot
, l'ambiguïté se pose une fois de plus, et le compilateur drapeau de la tentative d'appel(some instance of RoboticsEngineer).buildRobot();
comme une erreur.virtual
héritage de sens que pour l'héritage multiple, et Java a rien de tout cela, j'en doute, il...Il ne veut pas s'en occuper. C'est ambigu.
error C2385: ambiguous access of 'functionName'
Le compilateur est assez intelligent pour savoir qu'il ne devrait pas deviner vos sens.
Pour le programme à compiler, vous devez indiquer au compilateur que:
A. Vous savez que c'est un problème.
B. le Dire exactement ce que tu veux dire.
Pour ce faire, vous devez indiquer explicitement au compilateur de la méthode que vous proposez:
Le compilateur va se plaindre à propos de ce genre de situtation.
Dans un tel cas, c++ suggèrent de créer une Interface avec un "virtuelle pure" méthode buildRobot() fonction. MechanicalEngineer et EletricalEnginner va hériter de l'Interface et de remplacer les buildRoboot() fonction.
Lorsque vous créez RoboticsEnginner objet et l'appel de la buildRobot() de la fonction, l'interface de la fonction sera appelée.
Maintenant, quand vous le faites,
Un tel appel ne peut pas être résolu et est ambigu, car les deux sous-objets de a une fonction de membre avec la même signature et le compilateur ne sait pas qui appeler. Dans une telle situation, vous devez le mentionner explicitement à l'aide de
::
de l'opérateur ou à l'aide destatic_cast
.Il n'y a rien à propos de l'héritage de classe multiple qui permet ceci. Java produit le même problème avec les interfaces.
La réponse simple est que le compilateur génère une erreur sur elle.