views:

63

answers:

3
+3  Q: 

Inclusion problem

I have an inclusion pattern as follows:

/*
 * Class1.h
 */

#ifndef CLASS1_H_
#define CLASS1_H_

#include "Class2.h"

namespace Class1_namespace
{

class Class1
{
  Class2* Class2_ptr;
  void Class1_member()
  {
      (*Class2_ptr).Class2_method();
  }
};

}

#endif /* CLASS1_H_ */

/*
 * Class2.h
 */

#ifndef CLASS2_H_
#define CLASS2_H_

#include "Class1.h"

class Class2
{
    Class1_namespace::Class1 Class2_data;

public:
    void Class2_method(){};
};

#endif /* CLASS2_H_ */

/*
 * main.cpp
 */

#include "Class1.h"

int main()
{
    return 0;
}

However, this leads to the error “'Class1_namespace' does not name a type.”

Is this error caused by the ordering of my inclusions?

What are some possible solutions? I'm dubious about forward declarations solving my problem.

+2  A: 

Class1 doesn't need to include Class2.

When you have mutual dependency (which you don't -- you could just not include 2 in 1), you can usually solve it by using forward declarations instead of inclusions.

For example, let's say that Class1 looked like this

#include "Class2.h"

namespace Class1_namespace
{

    class Class1
    {
        Class2* class2;
    };

}

Where you think you need the include, you could instead do this:

class Class2;

namespace Class1_namespace
{

    class Class1
    {
        Class2* class2;
    };

}

to break the mutual inclusion.

Lou Franco
Is mutual inclusion always to be avoided, or just when forward declarations suffice?
Mutual inclusion is a symptom of cyclic dependencies, that should be avoided if possible. If you must have the cyclic dependency, then it can only be handled if one of the types can be forward declared. Else you will not be able to compile your code.
David Rodríguez - dribeas
If you think about what the #include actually does, you'll see why it couldn't possibly work the way you have it. The purpose of the preprocessor is to produce a single file which is then compiled. The compiler does a single pass through that file, so everything that is necessary for a class must come before it. Run your compiler setting to just preprocess and look at the result file -- you'll see it's impossible to compile it under those constraints.
Lou Franco
A: 

In class1.h, try removing the unnecessary and circular #include of class2.h. If a circular dependency is required -- or even if not -- consider using forward declarations.

Andy Thomas-Cramer
A: 

See the answer to my other question http://stackoverflow.com/questions/3410637/mutually-recursive-classes/3410714.