Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

breaking circular dependency?!

0 views
Skip to first unread message

Oliver Kowalke

unread,
Dec 28, 2008, 12:38:05 PM12/28/08
to
Hi,
how could following problem be solved (not the same base class)?

// A.h

class A
{
private:
   const X move_()
   { ... }

public:
   const B f()
   { return B( move_() ); }
};


// B.h

class B
{
private:
   const X move_()
   { ... }

public:
   const A f()
   { return A( move_() ); }
};

Rolf Magnus

unread,
Dec 28, 2008, 12:52:29 PM12/28/08
to
Oliver Kowalke wrote:

> Hi,
> how could following problem be solved (not the same base class)?

What base class?

> // A.h
>
> class A
> {
> private:
> const X move_()
> { ... }
>
> public:
> const B f()
> { return B( move_() ); }
> };
>
>
> // B.h
>
> class B
> {
> private:
> const X move_()
> { ... }
>
> public:
> const A f()
> { return A( move_() ); }
> };

Don't implement the functions in the header, but in the implementation file.
Then put a forward declaration before the class definition.


zr

unread,
Dec 28, 2008, 1:00:06 PM12/28/08
to

Oliver Kowalke

unread,
Dec 28, 2008, 1:31:13 PM12/28/08
to
Rolf Magnus wrote:

> Oliver Kowalke wrote:
>
>> Hi,
>> how could following problem be solved (not the same base class)?
>
> What base class?

I mean I don't want to have a (shared) base class (as a suggestion)

>> // A.h
>>
>> class A
>> {
>> private:
>> const X move_()
>> { ... }
>>
>> public:
>> const B f()
>> { return B( move_() ); }
>> };
>>
>>
>> // B.h
>>
>> class B
>> {
>> private:
>> const X move_()
>> { ... }
>>
>> public:
>> const A f()
>> { return A( move_() ); }
>> };
>
> Don't implement the functions in the header, but in the implementation
> file. Then put a forward declaration before the class definition.

forward declarations work for references or pointer in the header - doesn't
the compiler need to know the size of A / B in the header because it A and
B are returned by value and not as refernce or pointer?

Oliver Kowalke

unread,
Dec 28, 2008, 1:32:49 PM12/28/08
to
zr wrote:
> see
> http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.11
A and B are returned by value and not as references or pointers.

Rolf Magnus

unread,
Dec 28, 2008, 1:44:46 PM12/28/08
to
Oliver Kowalke wrote:

>> Don't implement the functions in the header, but in the implementation
>> file. Then put a forward declaration before the class definition.
>
> forward declarations work for references or pointer in the header -
> doesn't the compiler need to know the size of A / B in the header because
> it A and B are returned by value and not as refernce or pointer?

No.


blargg

unread,
Dec 28, 2008, 4:30:45 PM12/28/08
to
Rolf Magnus wrote:
> Oliver Kowalke wrote:
[...]
[simplified code]
> > // A.h
> > struct A {
> > const X move_() { ... }

> > const B f() { return B( move_() ); }
> > };
> >
> >
> > // B.h
> > struct B {
> > const X move_() { ... }

> > const A f() { return A( move_() ); }
> > };
>
> Don't implement the functions in the header, but in the implementation file.
> Then put a forward declaration before the class definition.

And if they must be inline, do this (with type X defined appropriately):

// A.h
struct B;

struct A {
const X move_() { ... }
const B f();
};

#include "B.h"

inline const B A::f() { return B( move_() ); }

// B.h
struct A;

struct B {
const X move_() { ... }
const A f();
};

#include "A.h"

inline const A B::f() { return A( move_() ); }

With proper include guards for A.h and B.h, the circular inclusion will
work properly.

Vaclav Haisman

unread,
Dec 29, 2008, 6:47:53 AM12/29/08
to
Using forward declaration and moving the methods implementation to place
where the forward declared class is complete. Something like this:


// X.h
struct X
{ };


// A.h
class B;

class A
{
private:
const X move_()

{ return X (); }

public:
A (X = X ())
{ }

const B f();
};


// B.h
class A;

class B
{
private:
const X move_()

{ return X (); }

public:
B (X = X ())
{ }

const A f();
};


// A.cpp
#include "A.h"
#include "B.h"

const B A::f()
{ return B( move_() ); }


// B.cpp
#include "A.h"
#include "B.h"

const A B::f()
{ return A( move_() ); }


// main.cpp
int main ()
{
A a;
B b;

A aa = b.f();
B bb = a.f();
}

0 new messages