2010-07-28 5 views
2

J'ai le problème de dépendance cyclique suivant, je suis en train de résoudre:Briser la dépendance cyclique en C++

typedef std::map<int, my_class> my_map; 

class my_class { 
... 
private: 
    my_map::iterator iter; 
}; 

class otherclass{ 
public: 
    my_map::iterator getIter(); 
private: 
    my_map map; 
}; 

Le compilateur n'aime pas, puisque my_class n'a pas été déclaré avant la typedef.

si je tente de transmettre-déclarer maclasse comme ceci:

class my_class; 

typedef std::map<int, my_class> my_map; 

class my_class { 
... 
private: 
    my_map::iterator iter; 
}; 

class otherclass{ 
public: 
    my_map::iterator getIter(); 
private: 
    my_map map; 
}; 

je reçois une « erreur: déclaration avant de« my_class ».

Comment puis-je rompre ce cercle vicieux? Je suis désolé mais je dois réviser ma question, car j'ai remarqué que ma représentation est légèrement fausse.

Ce qui suit est la représentation correcte de mon problème:

class my_container; 

typedef std::map<int, my_container> my_map; 

class my_class { 
... 
private: 
    my_map::iterator iter; 
}; 

class my_container { 
public: 
    my_class a_method(); 
private: 
    vector<my_class> v; 
}; 

class otherclass{ 
public: 
    my_map::iterator a_method(); 
    my_class another_method(); 
    my_container yet_another_method(); 
private: 
    my_map map; 
}; 

Désolé ce

+1

peut vous envoyer le message d'erreur exacte donnée par le compilateur? – Naveen

+1

En prenant une copie exacte du code ci-dessus et en supprimant le '...' de ma_classe compile dans VS2005 – Patrick

+1

L'exemple révisé compile également avec VS2010 même avec les extensions de langue désactivées. –

Répondre

2
class my_class; 

typedef std::map < int, my_class* > my_map; 
         ~~~~~~~~~~ use pointer here! 
+0

Veuillez ne pas utiliser de pointeurs. Cela conduira juste à des fuites car vous ne définissez pas explicitement la propriété des objets. –

+0

+1, bien que cela suppose que vous ne * voulez pas * l'ajouter à la carte pour provoquer une copie. C'est généralement vrai, cependant. @izex, avez-vous vraiment besoin de créer une copie complète de l'objet chaque fois que vous le placez sur la carte ou le lisez sur la carte?C'est généralement assez cher. En aparté, j'ai vraiment aimé shared_ptr <> pour ce problème: typedef std :: map > my_map; Il nettoie juste le mal de tête de gestion de mémoire d'employer un pointeur cru ici. –

0

mis my_map en tant que membre my_class, comme ceci:

class my_class { 
public:  typedef std::map<int, my_class> my_map; 
... 
private: 
     my_map::iterator iter; 
}; 

class otherclass{ 
public: 
     my_class::my_map::iterator getIter(); 
private: 
     my_class::my_map map; 
}; 

Si vous n » Je veux toujours utiliser my_class::, puis faire un autre typedef.

0

Vous pouvez mettre le typedef dans my_class:

class my_class { 
public: 
    typedef std::map<int, my_class> my_map; 
... 
private: 
    my_map::iterator iter; 
}; 

class otherclass{ 
public: 
    my_class::my_map::iterator getIter(); 
private: 
    my_class::my_map map; 
}; 
+0

Oui, cela devrait fonctionner, mais malheureusement, j'ai fait une erreur en formatant ma question, et ma situation est un peu plus compliquée. S'il vous plaît voir le message. – izex

1

dépendances circulaires sont généralement une mauvaise chose. Pouvez-vous repenser votre conception un peu? Est-ce qu'un my_class a vraiment besoin de savoir quel est le conteneur?

Si ce n'est pas pratique, au lieu d'un itérateur dans my_map, pourriez-vous sortir avec un my_container*? Le compilateur n'aura pas de problème avec l'utilisation d'un type incomplet pour le pointeur.

+0

Merci. Je sais que ce n'est pas trivial, mais dans mon cas, la dépendance circulaire est nécessaire. J'ai résolu le problème en utilisant my_container * en effet. – izex

0

Que diriez-vous:

#include <map> 

class my_class;       // forward declare the type. 
typedef std::map<int, my_class> my_map; 

class my_class 
{ 
    private: 
    my_map::iterator iter; 
}; 

class otherclass 
{ 
    public: 
    my_map::iterator getIter(); 
    private: 
    my_map map; 
}; 
Questions connexes