What're the benift and the drawback of defining a class embedded inside another class.

X

Xiangliang Meng

Hi, all.

What are the benefit and the drawback of defining a class embedded inside
another class?

For example:

class List
{
public:
int count;

class iterator
{
int index;
};
};

Is there any limitation on such a defination? Usually, under what kinds of
situation do we use it?

Thanks.

Best Regards,

Xiangliang Meng
 
T

ThosRTanner

Xiangliang said:
What are the benefit and the drawback of defining a class embedded inside
another class?
Is there any limitation on such a defination? Usually, under what kinds of
situation do we use it?

The worst drawback I've found in using this sort of syntax is that you
can't forward declare the contained class, so if you need to do

class List; //OK
class List::iterator; //Syntax error

you can't. It is stunningly annoying.
 
I

Ioannis Vranos

ThosRTanner said:
The worst drawback I've found in using this sort of syntax is that you
can't forward declare the contained class, so if you need to do

class List; //OK
class List::iterator; //Syntax error

you can't. It is stunningly annoying.


May you provide an example where this would be useful? I think you can't forward declare
the contained class for valid reasons. How the compiler could check whether the
declaration is correct, before reaching the class definition?
 
J

John Carson

Ioannis Vranos said:
May you provide an example where this would be useful?

It is useful for the same reasons it is useful with ordinary classes.
Suppose you have two inner classes, Inner1 and Inner2, and you want each to
store a pointer to the other.

You can, however, work around this problem by only forward declaring the
inner classes within the outer class, e.g.,

class Outer
{
class Inner1;
class Inner2;
};

class Outer::Inner1
{
Inner2 *ptr;
};

class Outer::Inner2
{
Inner1 *ptr;
};


I think you
can't forward declare the contained class for valid reasons. How the
compiler could check whether the declaration is correct, before
reaching the class definition?

That is no doubt the reason why it is not allowed. It is nevertheless
somewhat inconvenient.
 
I

Ioannis Vranos

John said:
It is useful for the same reasons it is useful with ordinary classes.
Suppose you have two inner classes, Inner1 and Inner2, and you want each
to store a pointer to the other.

You can, however, work around this problem by only forward declaring the
inner classes within the outer class, e.g.,

class Outer
{
class Inner1;
class Inner2;
};

class Outer::Inner1
{
Inner2 *ptr;
};

class Outer::Inner2
{
Inner1 *ptr;
};


I think this is a different case from the original.


That is no doubt the reason why it is not allowed. It is nevertheless
somewhat inconvenient.


Yes it is inconvenient. However I think it is for reasonable reasons. :)
 
T

ThosRTanner

Ioannis said:
May you provide an example where this would be useful? I think you can't forward declare
the contained class for valid reasons.

Given the existing convention that iterators are sub-classes of the
container over which they iterate, then

class Container
{
//...
class iterator
{
//...
}
//...
}

is not an unlikely scenario.

Under certain circumstances, it can be necessary for the iterator to
need to be a friend of the class contained in the container (don't ask,
it just is), and there is no way to order the declarations and stuff to
enable avoid forward declaring either the iterator class (which you
can't) or a proxy class which just wraps the iterator (which is a real
waste of time (and extra code to maintain, etc)). Changing the order of
declaration isn't applicable for various reasons.
How the compiler could check whether the
declaration is correct, before reaching the class definition?

In answer to your 2nd question - presumably the compiler determines
that the forward declaration is valid in exactly the same way it
determines that a forward declaration of class is valid. i.e. it
doesn't, it assumes that it is, until it finds another declaration of
Container::iterator which isn't a class. For instance, this is going to
be considered valid:

class Wibble;
std::eek:stream &std::eek:perator<<(str::eek:stream &, Wibble const &w);

until the compiler finds a declaration of Wibble which isn't a class. I
can't see why a subclass in here would confuse the compiler any more
(or less).

class Wibble;
class Wibble::Sub;
std::eek:stream &std::eek:perator<<(str::eek:stream &, Wibble::Sub const
&w);

I thought perhaps if Wibble::Sub was private, but even then the
implementation is going to need to get hold of the real definition of
Wibble::Sub and the compiler will error at that point (as indeed it
will if Wibble isn't a class, etc, etc). I'd really like to see the
reason why this isn't permitted.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top