1

--EDIT -- So sorry that I confused people, I just quickly typed this code out instead of copy and pasting, so I actually do #ifndef A_H #define A_H in my code. Ive changed the below code to show that
-- End edit --

I have two classes which each contain a pointer to an instance of the other class, but this is creating problems for me . My code is similar to the following

// A.h
#ifndef A_H
#define A_H

class B; // compiler error here

class A
{
  B* foo;
  // other members and functions
};

#endif

// A.cpp
#include "A.h"
#include "B.h"
/*
 declare functions and use methods in both A and B
*/

// B.h
#ifndef B_H
#define B_H

class A;

class B
{
  A** bar;
// other stuff
};

#endif

//B.cpp
#include "A.h"
#include "B.h" 
/*
declare functions and use methods in both A and B
*/

I was told that forward declaring the other class int he header file then including the other file in the cpp file would work, but on the marked line I get an error that just says "forward declaration of 'struct b'"

Can anyone tell me what I'm doing wrong?

Raphael
  • 127
  • 1
  • 10
  • 5
    I'm going to take a wild guess at your include guards messing up the class names. – chris Sep 09 '12 at 17:57
  • 1
    Agreed, `#define blah \n class blah` is going to be replaced with `class [nothing here]`. – Chris Eberle Sep 09 '12 at 18:00
  • @Raphael I advise you to read some authentic POSIX source code. They always use `#ifndef __FILENAME_H__` etc. –  Sep 09 '12 at 18:03
  • 1
    @H2CO3, Really? That's bad (at least for non-implementation code). I agree with the logic behind it, but http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier. I always use `FILENAME_H`. – chris Sep 09 '12 at 18:08
  • @OP, well with the includes commented out, the code [works on GCC 4.7.1](http://liveworkspace.org/code/2c3d20f4ab906439af31933e5c3a0cca). – chris Sep 09 '12 at 18:11
  • @chris I mean implementation code. And I'm aware of the presence of that question, but I'm not gonna obey its 'rules'. They're silly. –  Sep 09 '12 at 18:19
  • @H2CO3: the implementation is not allowed to use names like A_H because they are reserved for ordinary mortals (us) to use. Similarly, we're not allowed to use names that start with underscore because they're reserved for the implementation. The rules in the other question are not silly at all. They carve out independent chunks of the namespace so that both users and implementers can work without trampling on each other's code by accident. – Jonathan Leffler Sep 09 '12 at 18:27

1 Answers1

3

Include one header, let say b.h in a.h. Do not forward declare B in a.h. b.h can stay as it is.

Otherwise you get sth like

class B {};
....
class B;

It is always wise to do preprocessing only on such errors.

PiotrNycz
  • 23,099
  • 7
  • 66
  • 112