Dépendance cyclique

Résolu
K@zuya Messages postés 306 Date d'inscription vendredi 21 février 2003 Statut Membre Dernière intervention 15 février 2016 - 15 févr. 2016 à 00:21
K@zuya Messages postés 306 Date d'inscription vendredi 21 février 2003 Statut Membre Dernière intervention 15 février 2016 - 15 févr. 2016 à 20:35
Bonjour,

J'ai une dépendance cyclique que je ne parviens pas à résoudre.

Globalement, le problème est le suivant :
- J'ai une classe polymorphe (B hérite de A avec méthode virtuelle)
- J'ai un singleton, capable de faire A* a = new B();
- Mais mon polymorphe a besoin d'appeler le singleton pour faire des bricoles internes (B = C::GetInstance()->Bricoler())

Donc tout le monde appelle tout le monde, c'est le bazar... Voici un visuel qui peut éventuellement aider :


Voci également le code extrêmement simplifié, mais le problème est bien là, j'ai vérifié.

Le problème c'est que la façon dont les classes s'appellent, je ne peut pas faire de pré-déclaration genre : class A;
Ça me fait des erreurs...
Et si je ne le fait pas, j'ai également des erreurs...
Je sèche !!! Au secours....

Header de A
#ifndef __A__
#define __A__

#include "C.h"

class A
{
public:
virtual void Hello();
};

#endif

Corps de A
#include "A.h"

void A::Hello()
{
C::GetInstance()->Polymorphe();
}

Header de B
#ifndef __B__
#define __B__

#include "A.h"

class B : public A
{
public:
virtual void Hello();
};

#endif

Corps de B
#include "B.h"

void B::Hello()
{
C::GetInstance()->Polymorphe();
}

Header de C (singleton)
#ifndef __C__
#define __C__

#include "A.h"
#include "B.h"

class C
{
public:
inline static C* GetInstance()
{
return new C;
}

inline A* Polymorphe()
{
return new B();
}
};

#endif


2 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié par cptpingu le 15/02/2016 à 20:43
Bonjour.

En utilisant correctement les forward declaration, on s'en sort très bien :). Il faut bien comprendre que les forward vont dans le header, mais que les "include" doivent rester dans le corps. Il faut donc nécessairement découper ton fichier en deux si tu veux que ça fonctionne (une forward declaration n'est pas une déclaration "vue" par le link).

Pour reprendre ton exemple, j'ai fait ceci (qui compile, link et fonctionne):

A.h
#define __A__

#include "C.h"

class A
{
 public:
  virtual void Hello();
};

#endif


A.cc
#include "A.h"

void A::Hello()
{
  C::GetInstance()->Polymorphe();
}


B.hh
#ifndef __B__
#define __B__

#include "A.h"

class B : public A
{
 public:
  virtual void Hello();
};

#endif


B.cc
#include "C.h"
#include "B.h"

void B::Hello()
{
  C::GetInstance()->Polymorphe();
}


C.h
#ifndef __C__
#define __C__

class A;

class C
{
 public:
  static C* GetInstance();
  A* Polymorphe();
};

#endif


C.cc
#include "C.h"
#include "A.h"
#include "B.h"

C* C::GetInstance()
{
  return new C;
}

A* C::Polymorphe()
{
  return new B();
}


main.cc
#include "A.h"
#include "B.h"

int main()
{
  C* c = C::GetInstance();
  A* a = c->Polymorphe();
  a->Hello();

  return 0;
}



Améliorer votre expérience CodeS-SourceS avec ce plugin:
http://codes-sources.commentcamarche.net/forum/affich-10000111-plugin-better-cs-2#cptpingu-signature
0
K@zuya Messages postés 306 Date d'inscription vendredi 21 février 2003 Statut Membre Dernière intervention 15 février 2016
15 févr. 2016 à 20:35
Oh lala, trop puissant, ça marche !!!

Oui, en fait dans mes forward declarations, je n'avais pas fait le #include A, B dans le corps de C. C'est pour ça que ça ne fonctionnait pas, merci beaucoup. J'ai passé presque une journée à galérer sur ce problème.
0
Rejoignez-nous