Include l’intestazione circolare C ++

In un progetto ho 2 classi:

// 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]; }; 

Ma non riesco a compilare questo codice, ottenendo un errore static IFr ifr; linea. È proibito questo tipo di cross-inclusion?

Questo tipo di inclusioni incrociate è proibito?

Sì.

Una soluzione sarebbe dire che il membro ifr di mainw è un riferimento o un puntatore, in modo che una dichiarazione avanzata faccia invece di includere la dichiarazione completa, come:

 //#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; ... } 

In alternativa, definire il valore CSize in un file di intestazione separato (in modo che Ifr.h possa includere questo altro file di intestazione invece di includere mainw.h).

Non puoi avere due classi che si incorporano in questo modo. Potresti fare di uno di loro un puntatore:

 class foo; class bar { foo* fooPtr; } 

Dovresti build foo e assegnarlo a fooPtr nel costruttore della barra e liberarlo nel distruttore – è sicuramente un po ‘più di lavoro.

Oppure, in questo caso, come suggerito da uno dei commentatori, rendere mainw :: size a define e metterlo da qualche parte in comune.

Puoi fare ricorsive include in questo modo, ma in generale dovrai anche usare qualche tipo di trucco per la protezione dell’intestazione – altrimenti il ​​preprocessore andrà in una ricorsione infinita. Questo non ti aiuterà veramente a risolvere il problema sottostante, perché essenzialmente hai due classi, ognuna delle quali richiede reciprocamente di vedere la dichiarazione completa dell’altro per compilare:

 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 

Indipendentemente dal primo da inserire, non sarà ansible compilare perché è necessario conoscere tutti i dettagli dell’altro.

Questo tipo di inclusione circolare non è consentita da C ++, ma dovrebbe funzionare:

Invece di includere IFr.h, utilizzare una dichiarazione diretta.

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

Ciò farà compilare mainw bene, ma tutto il codice che usa il membro ifr deve includere anche IFr.h.

Funziona solo perché ifr è un membro static . Altrimenti, il compilatore dovrebbe conoscere la dimensione esatta di ifr .

Inoltre, come hanno detto molte altre persone, dovresti includere guardie attorno ad entrambe le intestazioni per evitare errori che provengono dall’includere due volte la stessa intestazione.

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

Tu puoi fare:

 // mainw.h #include "IFr.h" class mainw { public: static const size_t CSize=100; static IFr ifr; ... }; // IFr.h template  struct IFr { float sz_[Sz]; }; 

O nel caso in cui CSize debba cambiare in fase di esecuzione utilizzare una soluzione puntatore come mostra la risposta @ChrisW.

Se hai

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

avvolto attorno al tuo codice, allora dovresti stare bene 🙂

[EDIT] Compitazione del codice: O: P