-3

I cannot post any of my actual code due to the fact I am working with PS3 Dev kits and the source code is not allowed to be released publicly, so I will try my best to explain my problem without using any of the PS3 specific code.

Say I have 2 header file (A.h and B.h) along with 2 matching cpp files (A.cpp and B.cpp)

A.h looks similar to this

#ifndef A_H
#define A_H

#include "B.h"

class A
{
public:
    void function1();
    void functionA();
    B m_b;
};

#endif

While B.h looks like this

#ifndef B_H
#define B_H

#include "A.h"

class B
{
public:
    void function2();
    void functionB();
    A m_a;
};

#endif

Both these classes have other functions the the corresponding cpp files are required to used but I have left out. Within A.cpp I need to use all the functions from A.h and a single function from B.h and within B.cpp I need to use all the functions from B.h and a single function from A.h

So A.cpp currently looks similar to this:

#include A.h
#include B.h

void function1()
{
    code;
}

void functionA()
{
    code;
    m_b.function2();
}

and B.cpp looks like

#include A.h
#include B.h

void function2()
{
    code;
}

void functionB()
{
    code;
    m_a.function1();
}

Now obviously there is a lot more code than this but this is where I am getting the problem when compiling. I get the compiler error "Error 2 error 20: identifier "A" is undefined" and the matching "Error 2 error 20: identifier "B" is undefined". Why?

Daksh Shah
  • 2,997
  • 6
  • 37
  • 71
Lewie4
  • 9
  • 1
  • 2
  • 4
    possible duplicate of [Resolve circular dependencies in c++](http://stackoverflow.com/questions/625799/resolve-circular-dependencies-in-c) – Retired Ninja May 04 '14 at 05:35
  • 5
    Your code is impossible. If an `A` contains a `B`, and a `B` contains an `A`, it's turtles all the way down... – M.M May 04 '14 at 05:39
  • 1
    @user3600695: No, your fix is fake. The forward declaration of class `A` makes no sense. A class declared as `class A;` is incomplete and cannot be used to declare data members in another class. In other words, you forward declaration achieves nothing. – AnT stands with Russia May 04 '14 at 05:44
  • @FoggyDay: Include guards terminate the cycle. They don't in any way help to solve the circular dependence between declarations. This is why it never makes any sense to include header files circularly, guards or not. – AnT stands with Russia May 04 '14 at 05:46
  • "it should fix the problem" - famous last words – M.M May 04 '14 at 05:53
  • This can be deleted. Got some caffeine in me and fixed my circular dependency. Thanks anyways – Lewie4 May 04 '14 at 07:59

3 Answers3

2

Preprocessor syntax requires "" or <> around file names in #include directives. Why are you suddenly doing

#include A.h

in your .cpp files when in your .h files you were using a correct syntax

#include "A.h"

???

In any case, including header files into each other in circular fashion will not achieve anything meaningful.

Also, it looks like you are trying to make A a member of B and at the same time make B a member of A. It should be obvious to you that this is an infinitely nested data structure that cannot possibly exist in reality. It is not possible to do anything like that in C++.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Yeah, this was my just rushing out example code. The actual code is of course #include "A.h" – Lewie4 May 04 '14 at 08:01
0

A number of problems with this code. (Obviously the #include syntax in your cpp files is wrong, as has been pointed out).

Your A object contains a B, your B contains an A which contains a B which contains an A which contains a B......I think you get the idea.

You need to make at least one of those either a pointer or a reference. Then you need to use forward declaration to let the compiler know that B is a class:

// A.h
class B;
class A {
    // ...
    B * m_b;
};

// B.h
#include "A.h"
class B {
    // ...
    A m_a;
};

Note that the circular includes won't work. The include guard ensures that the preprocessor won't go into an infinite loop, but whichever class that appears first would not know what the other class is.

Your cpp code seems to also be defining the class members incorrectly - it should be:

void B::function2(){
    //code
}

and so on.

T.C.
  • 133,968
  • 17
  • 288
  • 421
-2

Use class pre-declaration as below:

In file A.h:

class B;
class A
{
...
private:
  B m_b;
};

In file B.h:

class B
{
...
private:
  A m_a;
};

In all cpp files, always include B.h after A.h.

#inlcude "A.h"
#inlcude "B.h"
Rico Wang
  • 89
  • 6