2009-08-15 2 views
13

In einem Projekt Enthält Ich habe 2 Klassen:Kreis C++ Header-

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

Aber ich kann diesen Code nicht kompilieren, einen Fehler bei der static IFr ifr; Zeile bekommen. Ist diese Art von Cross-Inclusion verboten?

+1

Ich nehme an, dass sollte mainw :: CSize sein –

Antwort

15

Ist diese Art von Cross -Einschlüsse sind verboten?

Ja.

Eine Behelfslösung wäre zu sagen, dass das ifr Mitglied mainw eine Referenz oder ein Zeiger ist, so dass eine zukunfts Erklärung stattdessen tut die volle Erklärung einschließlich, wie:

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

Alternativ Definieren Sie den CSize-Wert in einer separaten Header-Datei (so dass Ifr.h diese andere Header-Datei enthalten kann, anstatt mainw.h einzuschließen).

0

Wenn Sie bekam

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

um Ihren Code eingewickelt, dann sollten Sie sich gut :)

[EDIT]-Code Schreibweise: O: P

+0

Das würde in diesem Fall nicht helfen. – ChrisW

+0

Das würde in diesem Fall wirklich nicht helfen - es sollte offensichtlich sein, dass die Hauptklasse eindeutig die vollständige Deklaration der Ifr-Klasse sehen müsste, bevor sie kompilieren könnte. –

+0

Sie haben beide recht. Schätze, ich war ein bisschen zu schnell auf den Auslöser :) – cwap

4

Sie können nicht zwei Klassen haben, die sich auf diese Weise einbetten. Sie könnten einer von ihnen einen Zeiger machen:

class foo; 

class bar 
{ 
    foo* fooPtr; 
} 

Sie haben würden foo zu konstruieren und zu fooPtr zuweisen in bar Konstruktor und frei in der destructor - es auf jeden Fall ein bisschen mehr Arbeit.

Oder, in diesem Fall, wie einer der Kommentatoren vorgeschlagen, machen Sie mainw :: size eine Definition und setzen Sie es irgendwo gemeinsam.

1

Sie können rekursive Includes wie diese verwenden, aber im Allgemeinen müssen Sie auch einen Header-Guard-Trick verwenden - andernfalls wird der Präprozessor in eine unendliche Rekursion gehen. Dies wird nicht wirklich helfen, die zugrunde liegende Problem zu lösen, da Sie haben im Wesentlichen zwei Klassen, zu kompilieren, von denen jede für beide Seiten erfordern, um die vollständige Erklärung des anderen, um zu sehen:

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 

Egal, welches Sie setzen Erstens wird es nicht kompilieren können, weil es alle Details des anderen kennen muss.

+0

Und weil die vollständigen Details der anderen Klasse von jeder Klasse benötigt werden, hilft eine [Forward-Deklaration] (http://stackoverflow.com/q/553682/1497596) nicht. Wenn jedoch die Include-Datei für beispielsweise die Klasse "A" nur Zeiger oder Verweise auf die Klasse "B" enthält, kann eine Vorwärtsdeklaration für die Klasse "B" innerhalb der Klasse "A" die Kompilierung ermöglichen. – DavidRR

1

Diese Art von Kreis Aufnahme wird von C++ nicht erlaubt, aber dies sollte funktionieren:

Statt IFr.h von einschließlich einer Vorwärtsdeklaration verwenden.

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

Dies wird mainw Kompilierung machen ganz gut, aber alle Code, der das ifr Mitglied nutzt muss IFr.h gehören.

Dies funktioniert nur, weil ifr ein static Mitglied ist. Andernfalls müsste der Compiler die genaue Größe von ifr kennen.

Auch, wie viele andere Leute gesagt haben, sollten Sie Wächter um beide Überschriften einschließen, um Fehler zu vermeiden, die davon kommen, die gleiche Überschrift zweimal zu enthalten.

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

Sie tun können:

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

oder bei CSize muss zur Laufzeit ändern, um einen Zeiger Lösung als @ChrisW Antwort zeigt verwenden.