1

I have 2 classes that are causing an issue - Class "A" and Class "B". Class A has to be able to store objects of Class B but a function in Class B must take in arguments of Class A. The code I have is below.

Class A:

#ifndef INC_A
#define INC_A
#include "ClassB.h"

class ClassA
{
private:
    ClassB* b;
public:
    void Foo()
    {
        b = new ClassB;
        b->Foo2(this);
    }
}

#endif

Class B:

#ifndef INC_B
#define INC_B
#include "ClassA.h"

class ClassB
{
public:
    void Foo2(ClassA* a)
    {
        // Do stuff with "a" here
    }
}

#endif

The errors I get are below:

'ClassB::Foo2': function does not take 1 arguments

syntax error: identifier 'ClassA'

Is there a way around this seemingly infinite include loop?

Tom McKeown
  • 167
  • 7
  • Possible duplicate of [C++ #include Loop](https://stackoverflow.com/questions/30485817/c-include-loop) – Rama Feb 27 '18 at 15:23
  • Possible duplicate of [Resolve build errors due to circular dependency amongst classes](https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes) – drescherjm Feb 27 '18 at 15:46

3 Answers3

2

Simplest case:

#ifndef INC_A_AND_B
#define INC_A_AND_B

class ClassB; // forward declaration for B

class ClassA
{
private:
    ClassB* b; // usage of B
public:
    void Foo()
    {
        b = new ClassB;
        b->Foo2(this);
    }
};

// actual definition for B
class ClassB
{
public:
    void Foo2(ClassA* a)
    {
        // Do stuff with "a" here
    }
};

#endif

In more sophisticated scenario it maybe worth to extract abstract interfaces then make both classes as descendants to them.

Yury Schkatula
  • 5,291
  • 2
  • 18
  • 42
  • I tried to abstract the classes a little bit as its part of a larger project. I don't really understand how i would use forward declaration in this case as both the classes are used by others and need to be in seperate files. If I were to use forward declaration would there not be linking errors? – Tom McKeown Feb 27 '18 at 15:33
  • 1
    You can place both classes into the same h-file. Let me emphasize that in the code above. – Yury Schkatula Feb 27 '18 at 15:35
  • Ahh right, I have already set out both classes to be in seperate header files. Would it be bad practice to use the forward declaration then proceed to include the classB header file at the bottom? – Tom McKeown Feb 27 '18 at 15:38
-1

Yes, you need separate your class into header and implementation files( .h and .cpp) and then use forward definition. For example:

ClassA.h :

#ifndef INC_A
#define INC_A

class ClassB;

class ClassA
{
private:
    ClassB* b;
public:
    void Foo();
}

#endif    

ClassA.cpp :

#include "ClassA.h"

void ClassA::Foo() {
        b = new ClassB;
        b->Foo2(this);
}
adlerer
  • 1,010
  • 11
  • 14
-2

Try adding a semicolon to the end of your class definitions. For example:

class ClassB
{
public:
    void Foo2(ClassA* a)
    {
        // Do stuff with "a" here
    }
}; // <- semicolon
Marker
  • 972
  • 6
  • 9