3

i'm pretty new at using C++ and I'm actually stopped at a problem.

I have some class A,B,C defined as follow (PSEUDOCODE)

class A
{
...
    DoSomething(B par1);
    DoSomething(C par1);
...
}

class B
{
   A parent;
...
}

class C
{
   A parent;
...
}

The problem is :

How to make this? If I simply do it (as I've always done in c#) it gives errors. I pretty much understand the reason of this. (A isn't already declared if I add the reference (include) of B and C into its own header)

Any way to go around this problem? (Using void* pointer is not the way to go imho)

feal87
  • 927
  • 3
  • 11
  • 29
  • Do you want A to be the parent class of B and C? – Travis Gockel Mar 06 '10 at 14:30
  • Another thing: you really don't have a *reference* to parent in B and C. If you do: `A a; B b(a); C c(a);` then there will be three unrelated A instances, not one instance with two objects referring to it. If that is what you want rather use a pointer-to-A member. – UncleBens Mar 06 '10 at 14:59

4 Answers4

5

Forward-declare B and C. This way compiler will know they exist before you reach the definition of class A.

class B;
class C;

// At this point, B and C are incomplete types:
// they exist, but their layout is not known.
// You can declare them as function parameters, return type
// and declare them as pointer and reference variables, but not normal variables.
class A
{
    ....
}

// Followed by the *definition* of B and C.

P. S.

Plus, one more tip unrelated to the question (seeing how you come from a C# background): it's better to pass by const reference than by value:

class A
{
...
    void DoSomething(const B& par1);
    void DoSomething(const C& par1);
...
}
Community
  • 1
  • 1
Alex B
  • 82,554
  • 44
  • 203
  • 280
3

For function declarations, parameter types are allowed to be incomplete if the function is not defined there:

class B;
class C;

class A
{
...
    R DoSomething(B par1);
    R DoSomething(C par1);
...
}

class B
{
   A parent;
...
}

class C
{
   A parent;
...
}

inline R A::DoSomething(B par1) { ... }
inline R A::DoSomething(C par1) { ... }

So you just define them after B and C become complete. But since they are defined outside the class, make them inline so multiple definitions in different translation units won't cause linker errors.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • Also just make sure that you really want to copy the parameters. According to your needs, _maybe_ passing them by reference, such as DoSomething(B& par1) would be best. – rotoglup Mar 06 '10 at 14:35
2

You should forward declare classes B and C before A:

class B;
class C;

class A {
    ...
};

At the point where B and C are referenced within A, the compiler only needs to know what kind of animals these are. With the forward declaration you satisfy the compiler. Then later you can define them properly.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
1

use forward declaration

You can define class A; without it's implementation, before B and C, and then define it later

paquetp
  • 1,639
  • 11
  • 19