views:

850

answers:

6

In a project I have 2 classes:

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

But I cannot compile this code, getting an error at the static IFr ifr; line. Is this kind of cross-inclusion prohibited?

A: 

If you got

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

wrapped around your code, then you should be fine :)

[EDIT] Code spelling :O :P

cwap
That wouldn't help in this case.
ChrisW
This really wouldn't help in this case - it should be obvious that the mainw class would clearly need to see the full declaration of the Ifr class before it could compile
1800 INFORMATION
You are both right. Guess I were a bit too fast on the trigger :)
cwap
In many compilers the line `#pragma once` does the same thing
Otto Allmendinger
also, your header guard name is illegal. names containing double underscores or beginning with an underscore and an uppercase letter are reserved for the C++ implementation.
anon
+8  A: 

Is this kind of cross-inclusions are prohibited?

Yes.

A work-around would be to say that the ifr member of mainw is a reference or a pointer, so that a forward-declaration will do instead of including the full declaration, like:

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

Alternatively, define the CSize value in a separate header file (so that Ifr.h can include this other header file instead of including mainw.h).

ChrisW
+2  A: 

You can't have two classes that embed each other this way. You could make one of them a pointer:

class foo;

class bar 
{
    foo* fooPtr;
}

You'd have to construct foo and assign it to fooPtr in bar's constructor and free it in the destructor - it is definitely a bit more work.

Or, in this case, as one of the commenters suggested, make mainw::size a define and put it somewhere common.

stevex
A: 

You can do recursive includes like this, but in general you will also need to use some kind of header guard trick - otherwise the preprocessor will go into an infinite recursion. This will not really help you to resolve your underlying problem, because you essentially have two classes, each of which mutually require to see the full declaration of the other in order to compile:

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

No matter which one you put first, it will be unable to compile because it needs to know full details of the other one.

1800 INFORMATION
A: 

That kind of circular inclusion is not allowed by C++, but this should work:

Instead of including IFr.h, use a forward declaration.

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

This will make mainw compile just fine, but all code that uses the ifr member needs to include IFr.h too.

This only works because ifr is a static member. Otherwise, the compiler would need to know the exact size of ifr.

Also, as many other people have said, you should have include guards around both headers to avoid errors that come from including the same header twice.

#ifndef IFR_H
#define IFR_H
//...
#endif
CAdaker
+1  A: 

You can do:

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

Or in case CSize needs to change at runtime use a pointer solution as @ChrisW answer shows.

fnieto