By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,605 Members | 1,415 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,605 IT Pros & Developers. It's quick & easy.

n00b class question

P: n/a
Why can't I create an instance of A and B in the Class C definition?

#include <iostream>

class B;
class A;

class C {
public:
B b;
A a;
};

class B {
int b;
};

class A {
int a;
};

int main (void)
{
C c;

return 0;
}

Nov 10 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a

th********@gmail.com wrote:
Why can't I create an instance of A and B in the Class C definition?
Because class A and B are not yet defined.

Nov 10 '06 #2

P: n/a
th********@gmail.com wrote:
Why can't I create an instance of A and B in the Class C definition?

#include <iostream>

class B;
class A;

class C {
public:
B b;
A a;
};
To understand how to construct an instance of C, the compiler needs to
know what the internal structures of 'B' and 'A' are. Since you didn't
define (only declared) the classes 'B' and 'A' before 'C', the compiler
cannot do what it needs. Move the definition of 'C' _after_ 'B' and 'A'
definitions.
>
class B {
int b;
};

class A {
int a;
};

int main (void)
{
C c;

return 0;
}
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 10 '06 #3

P: n/a

Kavya wrote:
th********@gmail.com wrote:
Why can't I create an instance of A and B in the Class C definition?

Because class A and B are not yet defined.
Thanks for the reply,
I thought that the

class B;
class A;

at the start essentially helped the compiler know the rest of the
definition would be later on?How can I have it know about the
definition of A and B whilst still having them listed after C? (for a
more complicated problem which essentially means A contains B and B
contains A so reordering would not fix it.

AwooOOoo

Nov 10 '06 #4

P: n/a
th********@gmail.com wrote:
Thanks for the reply,
I thought that the

class B;
class A;

at the start essentially helped the compiler know the rest of the
definition would be later on?How can I have it know about the
definition of A and B whilst still having them listed after C? (for a
more complicated problem which essentially means A contains B and B
contains A so reordering would not fix it.

AwooOOoo
You cannot put B and C members in A unless B and C are defined first.
One reason is very fundamental: The compiler must know their size in
order to make them part of C.

You can, however, put pointers to B and C in A. The compiler knows what
size a pointer is :)

--
Scott McPhillips [VC++ MVP]

Nov 10 '06 #5

P: n/a
th********@gmail.com wrote:
I thought that the

class B;
class A;

at the start essentially helped the compiler know the rest of the
definition would be later on?
You seem to be asking a question here. The answer is "yes, you do
seem to have thought that".
>How can I have it know about the
definition of A and B whilst still having them listed after C?
"How can I have my cake and eat it too?"
(for a
more complicated problem which essentially means A contains B and B
contains A so reordering would not fix it.
The closing parenthesis is missing.

This is precisely the point. The compiler has to know the sizes of
the objects A and B so it can generate proper code. This is the
requirement of the language, mostly so that the compilers don't have
to be too sophisticated (which often means unimplementable).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 10 '06 #6

P: n/a

Scott McPhillips [MVP] wrote:
th********@gmail.com wrote:
Thanks for the reply,
I thought that the

class B;
class A;

at the start essentially helped the compiler know the rest of the
definition would be later on?How can I have it know about the
definition of A and B whilst still having them listed after C? (for a
more complicated problem which essentially means A contains B and B
contains A so reordering would not fix it.

AwooOOoo

You cannot put B and C members in A unless B and C are defined first.
One reason is very fundamental: The compiler must know their size in
order to make them part of C.

You can, however, put pointers to B and C in A. The compiler knows what
size a pointer is :)

--
Scott McPhillips [VC++ MVP]

Makes Sense. The example I'm playing with is to get familiar with
templates and the calling that I was trying to simplify is better
represented by,

template <class T>
class Balls {
public:
list<Sticks<T*s;
}

template <class T>
class Sticks {
public:
list<Balls<T*b;
}

So I want a list of pointers to the other templated class. I think this
means that I end up with a similar problem to what you described as s
and b are not pointers so the compiler doesn't know the size of the
list inside the class. Any thoughts on how to get around this? The idea
in the mock up would be that each class could contain a list of
pointers to the other class.

Appreciate your thoughts.

AwooOOoo.

Nov 10 '06 #7

P: n/a
th********@gmail.com wrote:
>
Kavya wrote:
>th********@gmail.com wrote:
Why can't I create an instance of A and B in the Class C definition?

Because class A and B are not yet defined.

Thanks for the reply,
I thought that the

class B;
class A;

at the start essentially helped the compiler know the rest of the
definition would be later on?How can I have it know about the
definition of A and B whilst still having them listed after C? (for a
more complicated problem which essentially means A contains B and B
contains A so reordering would not fix it.
You cannot have that. You will have to break the cycle by using an A* in B
or a B* in A (that is something for which a forwar declaration suffices!).

Think about it:

struct A {
int i;
B b;
};

struct B {
int j;
A a;
};

and ask yourself: will we have sizeof(A) < sizeof(B) because of the b in A
or will we have sizeof(B) < sizeof(A) because of the a in B? Obviously, you
would have both, which is a contradiction. Thus, you cannot do it.
Best

Kai-Uwe Bux
Nov 10 '06 #8

P: n/a
Hi,
Does this help:

class B;
class A
{
B* b;
};

class B
{
A* a;
};

Regards,
Tushar.

Kai-Uwe Bux wrote:
th********@gmail.com wrote:

Kavya wrote:
th********@gmail.com wrote:
Why can't I create an instance of A and B in the Class C definition?

Because class A and B are not yet defined.
Thanks for the reply,
I thought that the

class B;
class A;

at the start essentially helped the compiler know the rest of the
definition would be later on?How can I have it know about the
definition of A and B whilst still having them listed after C? (for a
more complicated problem which essentially means A contains B and B
contains A so reordering would not fix it.

You cannot have that. You will have to break the cycle by using an A* in B
or a B* in A (that is something for which a forwar declaration suffices!).

Think about it:

struct A {
int i;
B b;
};

struct B {
int j;
A a;
};

and ask yourself: will we have sizeof(A) < sizeof(B) because of the b in A
or will we have sizeof(B) < sizeof(A) because of the a in B? Obviously, you
would have both, which is a contradiction. Thus, you cannot do it.
Best

Kai-Uwe Bux
Nov 10 '06 #9

P: n/a

th********@gmail.com wrote:
Why can't I create an instance of A and B in the Class C definition?

#include <iostream>

class B;
class A;

class C {
public:
B b;
A a;
};

class B {
int b;
};

class A {
int a;
};

int main (void)
{
C c;

return 0;
}
The above is expected unless you use pointers or references to A,B in
class C.
This should still be a minor issue since each class above will probably
end up being declared in its own header and implemented in its own
source file. At least, that is what your goal should be once you have
the skeleton up and running.
As in...

/* ___ c.hpp ___ class C interface declaration */
#ifndef C_HPP_
#define C_HPP_ /* include guard */

#include "a.hpp"
#include "b.hpp"

class C
{
A a;
B b;
public:
C(); // def ctor
};

#endif /* include guard C_HPP_ */

/* ___ c.cpp ___ class C implementation */
#include "c.hpp"

// def ctor
C::C() : a(0), b(0)
{
}

Nov 10 '06 #10

P: n/a

<th********@gmail.comwrote in message
news:11**********************@m73g2000cwd.googlegr oups.com...
>
Scott McPhillips [MVP] wrote:
>th********@gmail.com wrote:
Thanks for the reply,
I thought that the

class B;
class A;

at the start essentially helped the compiler know the rest of the
definition would be later on?How can I have it know about the
definition of A and B whilst still having them listed after C? (for a
more complicated problem which essentially means A contains B and B
contains A so reordering would not fix it.

AwooOOoo

You cannot put B and C members in A unless B and C are defined first.
One reason is very fundamental: The compiler must know their size in
order to make them part of C.

You can, however, put pointers to B and C in A. The compiler knows what
size a pointer is :)

--
Scott McPhillips [VC++ MVP]


Makes Sense. The example I'm playing with is to get familiar with
templates and the calling that I was trying to simplify is better
represented by,

template <class T>
class Balls {
public:
list<Sticks<T*s;
}

template <class T>
class Sticks {
public:
list<Balls<T*b;
}

So I want a list of pointers to the other templated class. I think this
means that I end up with a similar problem to what you described as s
and b are not pointers so the compiler doesn't know the size of the
list inside the class.
No, that's not a problem. You're declaring a list which will hold pointers,
which is fine. The list size is dynamic; it grows when you add items to it.

Is that the actual code you have?

One problem is that you're missing semicolons (;) after the class
definitions. Also, you'd need to forward declare "template <class Tclass
Sticks;" before the Balls class. The it will compile fine.

But how do you try to use this code? What's T?

You could easily have code like this:

Sticks<Balls<int ballsticks;
Balls<Sticks<int stickballs;

Is that the kind of thing you meant to do?

-Howard

Nov 10 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.