J'essaie d'écrire des sous-classes de classes dans une grande bibliothèque. Je reçois une erreur "de base ambiguë". Voici un exemple compilable du problème:
#include <iostream>
// I can't change these because they are in the library:
class InteractorStyle {};
class InteractorStyleCamera : public InteractorStyle {};
class InteractorStyleImage : public InteractorStyle {};
// These are my subclasses (so I can change them):
class PointSelector : public InteractorStyle {};
class PointSelector2D : public InteractorStyleCamera, public PointSelector
{
// This function has to exist exactly like this (a requirement of the library):
static PointSelector2D* SafeDownCast(InteractorStyle *o)
{
return static_cast<PointSelector2D *>(o);
}
};
int main()
{
return 0;
}
L'erreur est
erreur: "InteractorStyle" est une base ambiguë de "PointSelector2D".
Y a-t-il quelque chose que je puisse faire dans ce cas?
Votre problème est que le style Interactor est hérité deux fois - une fois par PointSelector2D et une fois par InteractorStyleCamera. Cela signifie que vous avez 2 versions de chaque membre de celle-ci dans votre classe.
Check-out:
Comment puis-je éviter le Diamant de la Mort en utilisant l'héritage multiple?
Et essayez l'héritage virtuel.
Vous pouvez le "réparer" superficiellement en utilisant un casting en deux étapes. Par exemple
static_cast<PointSelector2D *>(static_cast<InteractorStyleCamera *>(o));
Bien sûr, vous devez garder à l'esprit que cela "corrige" la syntaxe, mais pas le problème structurel sous-jacent. Votre PointSelector2D
contient deux sous-objets InteractorStyle
base. Selon les sous-objets de base InteractorStyle
que vous démarrez, le chemin de la diffusion ascendante est différent. Et il est très important de prendre le bon chemin. Ce que j'ai écrit ci-dessus est pour InteractorStyle
à l'intérieur de InteractorStyleCamera
. Pour l’autre base, le upcast approprié serait
static_cast<PointSelector2D *>(static_cast<PointSelector *>(o));
Si un pointeur InteractorStyle *
ne contient que des informations supplémentaires sur la base pointée, il est impossible de résoudre votre problème avec static_cast
. Il n'y a aucun moyen de savoir quel chemin upcast prendre. Prendre le mauvais produira un résultat totalement dénué de sens.
Comme il a déjà été noté, dynamic_cast
peut aider dans cette situation, mais il a des exigences supplémentaires (type de départ polymorphe). Vos types ne sont pas polymorphes (du moins dans votre exemple cité), donc dynamic_cast
ne les acceptera pas pour les diffusions ultérieures.
Je crois que vous pouvez résoudre ce problème en utilisant un dynamic_cast
au lieu d'un static_cast
. Le dynamic_cast
peut examiner l'objet au moment de l'exécution pour déterminer laquelle des deux classes de base InteractorStyle
est pointée, puis à partir de là, il peut ajuster le pointeur au type approprié.
Vous pouvez obtenir votre code à compiler (votre exemple à compiler au moins) en ajoutant InteractorStyle
aux classes dont PointSelector2D
hérite. Je ne sais pas s'il s'agit d'une solution à long terme.