Dépendance cyclique [Résolu]

K@zuya 306 Messages postés vendredi 21 février 2003Date d'inscription 15 février 2016 Dernière intervention - 15 févr. 2016 à 00:21 - Dernière réponse : K@zuya 306 Messages postés vendredi 21 février 2003Date d'inscription 15 février 2016 Dernière intervention
- 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


Afficher la suite 

2 réponses

Répondre au sujet
cptpingu 3766 Messages postés dimanche 12 décembre 2004Date d'inscriptionModérateurStatut 1 décembre 2017 Dernière intervention - Modifié par cptpingu le 15/02/2016 à 20:43
0
Utile
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
Commenter la réponse de cptpingu
K@zuya 306 Messages postés vendredi 21 février 2003Date d'inscription 15 février 2016 Dernière intervention - 15 févr. 2016 à 20:35
0
Utile
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.
Commenter la réponse de K@zuya

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.