473,748 Members | 4,935 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Problem with Composition Relation/Forward Referencing.

Hi,

I was trying to implement a composition relation, somthing of the
following type:

class A
{
public:
class B
{
int member_of_B;
};

B b;
// ... some other members;
};
but as the defintion of B is too large I thought of may be writing it
outside. ;). So i modified the class as:
class A
{
class B;
B b;
....
};

class B {
int member_of_B;
};

We have two issues here:

1. anybody including "the .h" (in which i have declared the classes)
would get the type B and can use it. which i didn't intend to allow ;).

2. gcc 3.3.2 gave me an error of this type:

error: field `b' has incomplete type

Am I not allowed to use forward referencing ? What exactly does the
statement

class B;

in definition of A do? Doesn't it introduce the typename in A?

Any suggestions? Am I missing something obvious ?

~ M.

Sep 30 '05 #1
11 2809
Milind wrote:
Hi,

I was trying to implement a composition relation, somthing of the
following type:

class A
{
public:
class B
{
int member_of_B;
};

B b;
// ... some other members;
};
but as the defintion of B is too large I thought of may be writing it
outside. ;). So i modified the class as:
class A
{
class B;
B b;
...
};

class B {
int member_of_B;
};

We have two issues here:

1. anybody including "the .h" (in which i have declared the classes)
would get the type B and can use it. which i didn't intend to allow ;).

2. gcc 3.3.2 gave me an error of this type:

error: field `b' has incomplete type

Am I not allowed to use forward referencing ? What exactly does the
statement

class B;

in definition of A do? Doesn't it introduce the typename in A?
A couple of misunderstandin gs here. The correct way to make the forward
declaration is

class B;

class A
{
B b;
};

class B
{
};

Since class B is declared outside of class A, the forward declaration
must also be outside of class A.

But the second misunderstandin g is that an incomplete class (which is
what B is between the forward declaration and the actual declaration) is
only good for a very few things, for instance declaring pointers. In you
code the compiler needs to know the size of B in order to generate code
for A, but it does not know the size of B from just the forward declaration.

The obvious solution to this is just to reverse the order in which you
define your classes.

The other solution would be to rewrite A like this

class B;

class A
{
B* b;
};

By using a pointer you would not need to include the definition of B in
the header file at all. This might also help with your other requirement
that B not be usable by itself.

Any suggestions? Am I missing something obvious ?


Not obvious, but I'd guess you come from a Java background and haven't
quite absorbed yet that objects in C++ are values not references. Easily
the most fundamental difference between Java and C++.

john
Sep 30 '05 #2
> The correct way to make the forward
declaration is

class B;

class A
{
B b;
};

class B
{
};
Well Even that wont work ;( i copy pasted the above stuff and tried to
compile it with g++ 3.3.2 on my Debian box.

That thing apart,
Since class B is declared outside of class A, the forward declaration
must also be outside of class A.
As per my previous posting...
1. anybody including "the .h" .... "which i didn't intend to allow" ;).
I dont want anybody use class B directly, i always want others to use
it as A::B ,i.e as a part of class A. declaring in the way you
suggested will allow everyone else to use it as is.

making it a member would definitely impose using object of class B
inside A's object with this syntax. however, we can't stop ppl from
using bare class B objects.


But the second misunderstandin g is that an incomplete class (which is
what B is between the forward declaration and the actual declaration) is
only good for a very few things, for instance declaring pointers.
Yes; pointers work as they have same sizes and we dont allocate memory.
i tried that b4 posting here atfirst and it works fine. that is why i
got confused about forward referencing. if the type is known, why can't
the compiler do a second pass to allocate the mem ?
the compiler needs to know the size of B in order to generate code
for A, but it does not know the size of B from just the forward declaration.
that is why i asked: Am I not allowed to use forward referencing ? What exactly does the
statement

class B;

in definition of A do? Doesn't it introduce the typename in A?\
i mean doesn't the compiler do a second pass to get the size and
stuff??
The obvious solution to this is just to reverse the order in which you
define your classes.
hmmmm ..... but still if i define class B outside class A i will get it
exposed to anyone including the header file.

The other solution would be to rewrite A like this

class B;

class A
{
B* b;
};

By using a pointer you would not need to include the definition of B in
the header file at all. This might also help with your other requirement
that B not be usable by itself.

I dont know how by just declaring a pointer in a class can i restrict
B's usage. could you ellaborate please ?

I did try and implement this with private constructors and friend
functions. However that necessarilly means something else semantically.
i want to implement something like-> A::B always.
Any suggestions? Am I missing something obvious ?


Not obvious


Thnx. cause i was getting pretty worried :)
john


Thnx.
~M

Sep 30 '05 #3
Probably 'pimpl' idiom can help you:

http://www.gotw.ca/publications/mill04.htm

Bye
Fabio
Sep 30 '05 #4
Hey Fabio,

I think the pipl idiom is mostly concerning the avoiding of unnecessary
recompilations and opace interafaces for a class. The example that we
had a couple of days back on the group was regarding the size of a
std::string. i dont exactly believe that the idiom would be useful in
my case.

Thanks.
~M
FabioAng wrote:
Probably 'pimpl' idiom can help you:

http://www.gotw.ca/publications/mill04.htm

Bye
Fabio


Sep 30 '05 #5
Milind wrote:

Hey Fabio,

I think the pipl idiom is mostly concerning the avoiding of unnecessary
recompilations and opace interafaces for a class. The example that we
had a couple of days back on the group was regarding the size of a
std::string. i dont exactly believe that the idiom would be useful in
my case.

It would solve *exactly* your requirement of
1. anybody including "the .h" (in which i have declared the classes)
would get the type B and can use it. which i didn't intend to allow ;).


--
Karl Heinz Buchegger
kb******@gascad .at
Sep 30 '05 #6
Milind wrote:
Hi,

I was trying to implement a composition relation, somthing of the
following type:

class A
{
public:
class B
{
int member_of_B;
};

B b;
// ... some other members;
};
but as the defintion of B is too large
Why "too large"? Did you exceed compiler limits?

I thought of may be writing it outside. ;). So i modified the class as:
class A
{
class B;
B b;
...
};

class B {
int member_of_B;
};

We have two issues here:

1. anybody including "the .h" (in which i have declared the classes)
would get the type B and can use it. which i didn't intend to allow ;).
Well, this is not really a difference. With your original code, everybody
could declare objects of type B. One would just type A::B instead of B.
Now, you might say that this additional typing effort on part of the user
is exactly what you want to impose (sort of as a forced reminder). Well,
that won't fly either since everybody could just do a

typedef A::B B;

at the begining of their file to get rid of that restriction.

2. gcc 3.3.2 gave me an error of this type:

error: field `b' has incomplete type

Am I not allowed to use forward referencing ? What exactly does the
statement

class B;

in definition of A do? Doesn't it introduce the typename in A?


Well, it is a forward declaration inside the scope of A. The compiler should
complain when you do not follow that up by a real declaration inside that
scope.

Also, forward declarations are incomplete. The size of class B is not
deducible from a forward declaration. Thus, the compiler cannot deduce how
much memory is needed for the member object b.
Best

Kai-Uwe Bux
Sep 30 '05 #7
Milind wrote:
The correct way to make the forward
declaration is

class B;

class A
{
B b;
};

class B
{
};

Well Even that wont work ;( i copy pasted the above stuff and tried to
compile it with g++ 3.3.2 on my Debian box.


Well no, it wasn't intended to work, it only corrects the first of your
errors, not the second.

That thing apart,

Since class B is declared outside of class A, the forward declaration
must also be outside of class A.

As per my previous posting...
1. anybody including "the .h" .... "which i didn't intend to allow" ;).

I dont want anybody use class B directly, i always want others to use
it as A::B ,i.e as a part of class A. declaring in the way you
suggested will allow everyone else to use it as is.


OK, well then the only choice you have is to declare B inside of A.

making it a member would definitely impose using object of class B
inside A's object with this syntax. however, we can't stop ppl from
using bare class B objects.
But the second misunderstandin g is that an incomplete class (which is
what B is between the forward declaration and the actual declaration) is
only good for a very few things, for instance declaring pointers.

Yes; pointers work as they have same sizes and we dont allocate memory.
i tried that b4 posting here atfirst and it works fine. that is why i
got confused about forward referencing. if the type is known, why can't
the compiler do a second pass to allocate the mem ?


It just doesn't, C++ was designed that way. Makes life easier for the
compiler writers I guess.

john
Sep 30 '05 #8
On Fri, 30 Sep 2005 06:48:50 GMT, John Harrison
<jo************ *@hotmail.com> wrote in comp.lang.c++:

[snip]
A couple of misunderstandin gs here. The correct way to make the forward
declaration is

class B;

class A
{
B b;
};

class B
{
};


ITYM either:

class A
{
B *b;
};

....or:

class A
{
B &b;
};

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Oct 1 '05 #9
>
OK, well then the only choice you have is to declare B inside of A.
Can i have something like: A::B definition for A?
It just doesn't, C++ was designed that way. Makes life easier for the
compiler writers I guess.

Oh.. okay.
john


Oct 1 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
2480
by: Dave | last post by:
Hi I'm making a 3D Engine which consists of the class C3DEngine. Part of this engine is a file loader, a class called CMeshLoader. I have made an instance of CMeshLoader in C3DEngine, ie composition. Unfortunately, CMeshLoader sometimes needs to refer to private members of C3DEngine. Inheritance, friends, and composition are all swirling around in my head at the moment. I know that inheritance is not the solution. Can someone please...
4
2675
by: fog | last post by:
Given: class A; and B "has-a" A. The composition relationship between A and B can be implemented in three ways: =================== # 1. class B {
10
4634
by: Florian G. Pflug | last post by:
Hi I installed a postgres-application (which was developed on debian woody) on red hat 9 today, using the postgres 7.3 rpms from redhad. One of my the triggers uses the pg_settings table (more precisely, it updates that table to change the search_path temporarily). With the postgres 7.3 (and 7.4 too) installed on my debian development system, this worked fine. On redhat 9, however, I get an "pg_settings: permission denied" error when my...
2
1195
by: Christopher Benson-Manica | last post by:
Are these terms semantically identical? If so, which is to be preferred when speaking of the construct they describe? -- Christopher Benson-Manica | I *should* know what I'm talking about - if I ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
2
1622
by: pei_world | last post by:
can anyone help me with these problem, code written correctly except those with * mark. //========================================================================== =============================== //recursive function defined for print nodes private void nodePrint(TreeNode rootNode,string parentidstr,SqlDataAdapter sqlDANode,DataSet tmpDS) { bool printed=false; try
4
14449
by: Frederik Vanderhaegen | last post by:
Hi, Can anyone explain me the difference between aggregation and composition? I know that they both are "whole-part" relationships and that composition parts are destroyed when the composition whole is destroyed. Under a "whole-part" relationship I understand the following: the whole can't exists without the parts, but can the parts exist without the hole? f.e.: a car can't exist without an engine private engine _Engine
1
1309
by: tony | last post by:
Hello! I access the class MyComparer in this way. steel_post.Sort(new MeltPracDataComposition.Composition.MyComparer()); You can see the class definition for MyComparer below. As you can see this class MyComparer in located withing class Composition and this class Composition is located within class MeltPracDataComposition.
4
5504
by: fireball | last post by:
hi, I got confused for a moment about creating data structure for UML composition (strong aggregation) relation one-to-many. I used Rose/DataModeler to do so. <filled_diamond>-------- I got P/FK (primary key of my component is foreign key of it's container) in my child table: Parent: PK Parent_ID
1
3012
by: Zeljko Bilandzija | last post by:
Hello! I have a problem, and I looking for help if someone can handle this. I use asp.net 2.0, and I create web site which support users from internet (Web Site Administration Tool) and with that option i get database named ASPNETDB.MDF. When someone via page is creating account, database creates a new record in aspnet_users table. I made another table (table User_Data, columns UserID, Level, Points, ...), and i want that these data...
0
8991
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8830
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9370
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9247
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8242
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6796
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6074
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
2
2782
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2215
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.