ABu
ABu

Reputation: 12279

Avoiding circular dependence?

Related to a previous question, I have now the following one:

In the next scenery:

class B;

class A
{
   // stuff, methods and so on
   B b;
};

class B
{
   // stuff, methods and so on
   A a;
};

Here we have a circular dependence between A and B, but this code is ill-formed since B is an incomplete type. A solution is to change B by a pointer of B by means of a smart pointers for example. But adding pointer add complexity and resources spending unnecesarily since you don't need a pointer!

In the previous question I tried to avoid the use of pointers by means of templates, so I delay the instantation of the class at a point where both classes are defined, but I was incapable of doing it successfuly.

Is it impposible to avoid pointers? Are there well-known dessigns to avoid circular dependences?

Upvotes: 1

Views: 240

Answers (3)

dyp
dyp

Reputation: 39121

I don't think it's primarily a problem of the compiler (it cannot do that, though) but rather a problem in your design: A data member expresses ownership. If A has a data member of type B, then an instance of A owns an instance of B.

If the same holds for B, then you'll either get circular ownership (a owns b and b owns a) or a infinite series of a0 owns b0 owns a1 owns b1 .....

Therefore, you'll have to express for at least one of the two types that the instances don't own instances of the other type. You can do this in C++ using (smart) pointers or references, or passing the object to each member function of the class where it's required.

Upvotes: 3

David Heffernan
David Heffernan

Reputation: 613053

It is impossible to avoid some form of reference, for example pointers.

As you are trying it to do it, there is an infinite recursion in the definition. An A includes a B which includes and A, and so on for ever more. So, both classes would require infinite storage which is obviously nonsensical.

If you really have a model where A contains B and B contains A then these classes appear to be incapable of living without each other. In which case perhaps you only really have one class and not two.

Upvotes: 8

Ed Heal
Ed Heal

Reputation: 60007

The compiler has to figure out the space required for a B.

How does it do this? It works out that the space required is the size of an A.

But the size of an A is the size of a B. Back to square one and the compiler would have to loop forever to figure it out. Hence it does not compile.

The only solution is to break this cycle i.e use a pointer (smart or otherwise).

Upvotes: 7

Related Questions