J’ai besoin d’aide pour une implémentation utilisant plusieurs inheritances d’interfaces …
Il y a un code existant avec une interface qui a beaucoup de fonctions. Les instances sont créées à l’aide d’une fabrique.
class IBig { // Lot of pure virtual functions };
Et son implémentation:
class CBig: public IBig { // Implementation }
Je souhaite diviser l’interface en plusieurs interfaces plus petites, mais elle doit restr compatible avec le code existant pendant un certain temps.
Voici un exemple de ce que j’ai essayé de faire:
class IBaseA { public: virtual void DoA() = 0; }; class IBaseB { public: virtual void DoB() = 0; }; // The same interface, now based on multiple smaller interfaces class IBig : public IBaseA, public IBaseB { }; class CBaseA: public IBaseA { public: virtual void DoA() { printf("DoA\n"); } }; class CBaseB: public IBaseB { public: virtual void DoB() { printf("DoB\n"); } }; // Inherit from base classes where the implementation is, and from IBig as // the instance of CBig is returned as IBig. class CBig: public CBaseA, public CBaseB, public IBig { };
Le problème ici est que la classe CBig ne peut pas être instanciée. Le compilateur dit que les fonctions DoA et DoB sont purement virtuelles, même si elles sont implémentées dans CBaseA et CBaseB. Que dois-je faire si je ne veux pas réimplémenter les fonctions, juste pour appeler la fonction de la classe de base?
NB: Je sais que le design est moche, mais ce n’est que temporaire jusqu’à ce que la grande interface puisse être remplacée, et …. je veux comprendre! 😉
Merci d’avance !
Ici, vous devez utiliser l’inheritance virtuel . Cette fonctionnalité garantit qu’il n’y a qu’une seule instance de votre classe de base virtuellement héritée lorsque vous instanciez une sous-classe. Pour votre exemple, cela ressemblerait à:
#include class IBaseA { public: virtual void DoA() = 0; }; class IBaseB { public: virtual void DoB() = 0; }; // The same interface, now based on multiple smaller interfaces class IBig : virtual public IBaseA, virtual public IBaseB // ^ ^ { }; class CBaseA: virtual public IBaseA // ^ { public: virtual void DoA() { printf("DoA\n"); } }; class CBaseB: virtual public IBaseB // ^ { public: virtual void DoB() { printf("DoB\n"); } }; // Inherit from base classes where the implementation is, and from IBig as // the instance of CBig is returned as IBig. class CBig: public CBaseA, public CBaseB, public IBig { }; int main() { CBig cb; }
Les modifications ci-dessus garantissent qu’il n’y a pas de déclarations supplémentaires de DoA
et de DoB
créées lorsque vous IBaseA
de IBaseA
et IBaseB
plusieurs resockets.
Ceci est connu comme le diamant mortel de la mort (ou simplement le problème du diamant). Cela se produit car CBig hérite de classes qui partagent des classes de base communes.
Vous pouvez soit appeler le bon DoA en le préfixant avec la classe à laquelle il appartient
CBaseA::doA();
ou vous utilisez l’inheritance virtuel pour n’avoir qu’une seule instance d’IBaseA et IBaseB
class CBaseA : public virtual IBaseA {}; class CBaseB : public virtual IBaseB {}; class IBig : public virtual IBaseA, public virtual IBaseB {};
etc…