5

Hi I already read similar questions about this topic, but I coudn't resolve my problem. I think I have to do a forward declaration so I tried the following.

I have three classes A, B and InterfaceA

Defintion InterfaceA

#ifndef INTERFACE_A_H
#define INTERFACE_A_H
#include "B.h"

namespace Example
{
  class B; // Forward declaration?
  class InterfaceA
  {
     Example::B test;

   };

}

#endif 

Definiton class A

#ifndef A_H
#define A_H
#include "InterfaceA.h"
namespace Example
{
  class A : public Example::InterfaceA
  {

  };
}
#endif

Defintion class B

#ifndef B_H
#define B_H
#include "A.h"

namespace Example
{
  class A; // Forward declaration?
  class B
  {
     Example::A test;
  };

}

#endif

main

#include "A.h"
#include "B.h"
int main()
{
  Example::A a;
  Example::B b;
}

I get the following error in visual studio:

'Example::B::test' uses undefined class 'Example::A'

Edit: Thank you so far, for all the help. It was very helpful. I think my problem was that I had a very poor design in my real project. I will change that.

Beside that I have now a better understanding for forward declarations :-)

TruckerCat
  • 1,437
  • 2
  • 16
  • 39
  • 1
    Since both class `A` and `B` reference each other *by value* there is nothing to do but either redesign or by making one (or both) references or pointers. – Some programmer dude Nov 26 '14 at 08:52
  • 1
    If `A` contains a `B`, then `B` can't contain an `A`. One or other of the `test` variables will have to be a pointer or reference, in which case that type only needs to be declared, not defined. – Mike Seymour Nov 26 '14 at 08:52

3 Answers3

5

If you really need that class A references class B and viceversa, instead of having instances of A and B as data members, consider using pointers, e.g. something like this:

// A.h

#pragma once

#include <memory> // for std::unique_ptr

// Forward declaration (A references B using pointer)
class B;

class A 
{
...
    std::unique_ptr<B> m_pB;
};

And similarly:

// B.h

#pragma once

#include <memory> // for std::unique_ptr

// Forward declaration (B references A using pointer)
class A

class B 
{
...
    std::unique_ptr<A> m_pA;
};

PS
Not related to the core of your question, however note that I used #pragma once instead of "old style" #ifndef/#define/#endif include guards; #pragma once seems simpler and clearer to me.

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
  • But `#pragma once` is non-standard – Basile Starynkevitch Nov 26 '14 at 09:38
  • @BasileStarynkevitch: I think `#pragma once` is supported by the most important and widespread C++ compilers: GCC, Clang and MSVC. Anyway, if it is non-standard, I'd suggest the C++ committee to standardize it. – Mr.C64 Nov 26 '14 at 11:04
  • I am currently working on a microcontroller based project. I am using C and C++. That's why I can't use #pragma once. Anyway I think #pragma once should become a standard. – TruckerCat Nov 26 '14 at 13:22
3

You are creating circular dependency. Revise your design.

Do you really need an instance of class A inside B and B inside A?

Alexus
  • 942
  • 7
  • 20
0

make them both inherit from the same parent header file, if they need to share header information.