2009-08-15 12 views
13

Dans un projet, j'ai 2 classes:circulaire C++ en-tête comprend

// mainw.h

#include "IFr.h" 
... 
class mainw 
{ 
public: 
static IFr ifr; 
static CSize=100; 
... 
}; 

// IFr.h

#include "mainw.h" 
... 
class IFr 
{ 
public float[mainw::CSize]; 
}; 

Mais je ne peux pas compiler ce code, obtenir une erreur à la ligne static IFr ifr;. Est-ce que ce type d'inclusion croisée est interdit?

+1

Je suppose que devrait être mainw :: CSize –

Répondre

15

Est-ce ce genre de croix -les inclusions sont-elles interdites?

Oui.

Un travail autour serait de dire que le député de ifr de mainw est une référence ou un pointeur, de sorte qu'un avant-déclaration fera au lieu d'inclure la déclaration complète, comme:

//#include "IFr.h" //not this 
class IFr; //this instead 
... 
class mainw 
{ 
public: 
static IFr* ifr; //pointer; don't forget to initialize this in mainw.cpp! 
static CSize=100; 
... 
} 

Alternativement , définissez la valeur CSize dans un fichier d'en-tête séparé (de sorte que Ifr.h puisse inclure cet autre fichier d'en-tête au lieu d'inclure mainw.h).

0

Si vous avez

#ifndef __MYHEADER_NAME_WHICH_IS_RANDOM_PER_FILE_H 
#define __MYHEADER_NAME_WHICH_IS_RANDOM_PER_FILE_H 
//... Code.. 
#endif 

enroulé autour de votre code, alors vous devriez être bien :)

[EDIT] Code de l'orthographe: O: P

+0

Cela ne aiderait pas dans ce cas. – ChrisW

+0

Cela n'aiderait vraiment pas dans ce cas - il devrait être évident que la classe mainw aurait clairement besoin de voir la déclaration complète de la classe Ifr avant de pouvoir compiler –

+0

Vous avez tous les deux raison. Je suppose que j'étais un peu trop rapide sur le déclencheur :) – cwap

4

Vous ne pouvez pas avoir deux classes qui s'imbriquent les unes les autres de cette façon. Vous pouvez faire l'un d'eux un pointeur:

class foo; 

class bar 
{ 
    foo* fooPtr; 
} 

Il faudrait construire foo et l'affecter à fooPtr dans le constructeur de bar et une dans la destructor - il est certainement un peu plus de travail.

Ou, dans ce cas, comme l'un des commentateurs l'a suggéré, faites mainw :: size a define et placez-le dans un endroit commun.

1

Vous pouvez faire des inclusions récursives comme ceci, mais en général vous devrez également utiliser une sorte de tour de garde d'en-tête - sinon le préprocesseur ira dans une récursion infinie. Ce ne sera pas vraiment vous aider à résoudre votre problème sous-jacent, parce que vous avez essentiellement deux classes, chacune nécessitant mutuellement pour voir la pleine déclaration de l'autre afin de compiler:

class mainw 
{ 
public: 
static IFr ifr; // needs to see the full declaration of the Ifr class in order to know the size 
... 

class IFr 
{ 
public float[mainw::size]; // needs to see the full declaration of mainw in order to know what size is 

Peu importe celui que vous mettez Premièrement, il sera incapable de compiler parce qu'il a besoin de connaître tous les détails de l'autre.

+0

Et parce que tous les détails de l'autre classe sont nécessaires pour chaque classe, une [déclaration avant] (http://stackoverflow.com/q/553682/1497596) n'aide pas. Cependant, si le fichier include de say, classe 'A', contient uniquement des pointeurs ou des références à la classe' B', alors une déclaration forward vers la classe 'B' dans la classe' A' peut rendre la compilation possible. – DavidRR

1

Ce genre d'inclusion circulaire n'est pas autorisé par C++, mais cela devrait fonctionner:

Au lieu d'inclure IFr.h, utilisez une déclaration avant.

class IFr; 
class mainw 
{ 
    //... 
}; 

Cela rendra mainw compilation très bien, mais tout le code qui utilise le membre ifr doit inclure IFr.h aussi.

Cela ne fonctionne que parce que ifr est un membre static. Sinon, le compilateur devrait connaître la taille exacte de ifr. De plus, comme beaucoup d'autres personnes l'ont dit, vous devriez inclure des gardes autour des deux en-têtes pour éviter les erreurs qui peuvent survenir si vous incluez deux fois le même en-tête.

#ifndef IFR_H 
#define IFR_H 
//... 
#endif 
1

Vous pouvez faire:

// mainw.h 

#include "IFr.h" 
class mainw { 
public: 
    static const size_t CSize=100; 
    static IFr<CSize> ifr; 
... 
}; 

// IFr.h 
template <size_t Sz> 
struct IFr { 
    float sz_[Sz]; 
}; 

ou en cas cSize doit changer lors de l'exécution d'utiliser une solution de pointeur comme le montre la réponse @ChrisW.

Questions connexes