2013-05-15 3 views
2

J'ai deux classes, disons classe A et classe B. Mon but est que les deux classes utilisent les unes avec les autres fonctions. Le problème est, la structure d'inclusion multi-fichiers ne semble pas me laisser faire cela. Voici ce que je suis en train de faire:Classes C++ utilisant les uns les autres

#file A.h 

Class A{ 
public: 
    int GetInfo(); 

private: 
    B * ptrToB; 
}; 

#file B.h 

Class B{ 
public: 
    int getStuff(); 
private: 
    A * ptrToA; 
}; 

Mon but est une Une méthode de classe pour être en mesure d'appeler ptrToB->getStuff() et pour une méthode de classe B pour pouvoir appeler ptrToA->getInfo()

Est-ce possible? Comment? Si non, pourquoi pas?

+1

D'autres ont montré la voie pour le compiler, mais demandez-vous pourquoi vos classes doivent être couplées. Soit en faire une classe, soit mettre les bonnes données sur la bonne classe. N'utilisez pas de getters. Dites à la classe avec les données de faire la bonne chose avec ces données. Recherchez [Data Envy] (http://c2.com/cgi/wiki?DataEnvy), et d'autres. –

+0

duplication possible de [classes mutuellement récursives] (http://stackoverflow.com/questions/3410637/mutually-recursive-classes) – ecatmur

Répondre

4

Vous utilisez peut-être des déclarations forward?

#file A.h 

#ifndef ACLASS_H 
#define ACLASS_H 

Class B; 

Class A{ 
public: 
    int GetInfo(); 

private: 
    B * ptrToB; 
}; 

#endif 

Puis dans le fichier CPP. La même chose serait faite pour les fichiers B classes H et CPP.

Une définition directe permet au compilateur de reconnaître un type sans qu'il soit nécessaire de le définir explicitement. Si vous aviez une référence à un B dans la classe A, vous devez inclure l'en-tête de B.

Étant donné que vous utilisez un pointeur pour accéder à B, le compilateur n'a pas besoin de connaître les données internes avant d'y accéder (dans le fichier CPP).

// Would need the header because we must know 
// the size of B at compile time. 
class B; 
class A 
{ 
    B theB; 
} 


// Only need forward declaration because a 
// pointers size is always known by the compiler 
class B; 
class A 
{ 
    B * bPointer; 
} 
+0

Wow une autre bonne réponse. – RandyGaul

+0

Merci, ça marche! J'ai essayé cela plus tôt, sauf que j'ai essayé d'appeler aPointer-> AMemberFunc() à partir d'une fonction inline dans le fichier B.h.Je suppose que la clé à ceci est des déclarations avant dans le fichier d'en-tête, suivi par l'inclusion dans le fichier .cpp? Est-ce spécifiquement pour éviter les dépendances circulaires? – Nathan

+0

Oui, vous pouvez le faire soit pour cacher l'implémentation de quelque chose et pour éviter les dépendances circulaires. –

2

il suffit d'ajouter une déclaration avant de déposer A.h, de sorte que le compilateur sait qu'un B* est un pointeur vers une classe que vous définirez plus tard:

class B; 

Définissez ensuite votre class A et comprennent B.h après. De cette façon, tout le monde, y compris A.h aura class A et class B défini.

Dans B.h, ajoutez simplement A.h au début. De cette façon, tout utilisateur, y compris B.h, aura également défini class A et class B. Lorsque vous définissez vos fonctions dans les fichiers .cpp associés, vous disposez des deux classes disponibles et pouvez simplement écrire vos fonctions comme vous le souhaitez.

Ce problème est appelé mutual recursion.

+0

+1 pour explication plutôt que le code prêt à être utilisé ... (ce qui est bien sûr aussi bien;)) Bonne réponse. – leemes

2

Vous pouvez utiliser avant la déclaration de dépendances briser:

#file A.h 

Class A{ 
public: 
    int GetInfo(); 

private: 
    B * ptrToB; 
}; 

#file B.h 
struct A; 
Class B{ 
public: 
    int getStuff(); 
private: 
    A * ptrToA; 
}; 

Ensuite, vous pouvez inclure dans A.h B.cpp et B.h en A.cpp sans problème.

Questions connexes