Nested class

N

newbiecpp

Why this code cannot be compiled (under VC++ 7.0):

class Outer {
public:
class Inner {
public:
Inner() : in_data(0) {}
void action()
{
Outer::eek:ut_data++; // illegal reference to non-static
member 'Outer::eek:ut_data'
}

int in_data;
};

Outer() : out_data(0) {}
void action()
{
Inner::in_data++; // ittlegal reference to non-static member
'Outer::Inner::in_data'
}

int out_data;
};

Thanks in advance!
 
G

Gianni Mariani

newbiecpp said:
Why this code cannot be compiled (under VC++ 7.0):

class Outer {
public:
class Inner {
public:
Inner() : in_data(0) {}
void action()
{
Outer::eek:ut_data++; // illegal reference to non-static
member 'Outer::eek:ut_data'
}

int in_data;
};

Outer() : out_data(0) {}
void action()
{
Inner::in_data++; // ittlegal reference to non-static member
'Outer::Inner::in_data'
}

int out_data;
};

It should not compile on any standard C++ compiler.

In C++, an inner class is just a type definition, you need to
specifically instantiate an object.

e.g.
Outer::Inner my_inner_object;

in some funtion
....
++ my_inner_object.in_data;
....

would do what you want.

You can obviously have a member variable in Outer that also instaniates
the Inner class.

e.g.
class Outer {
.....
Inner m_inner;
.....
void func()
{
++ m_inner.in_data;
}
};
 
R

Rolf Magnus

newbiecpp said:
Why this code cannot be compiled (under VC++ 7.0):

class Outer {
public:
class Inner {
public:
Inner() : in_data(0) {}
void action()
{
Outer::eek:ut_data++; // illegal reference to
non-static member 'Outer::eek:ut_data'

That's exactly the problem. Outer::eek:ut_data is a non-static member, you
need an object to access a non-static member of. So you need an object
of class Outer to increment its member out_data, or you need to declare
that member static, depending on what you actually need.
}

int in_data;
};

Outer() : out_data(0) {}
void action()
{
Inner::in_data++; // ittlegal reference to non-static
member 'Outer::Inner::in_data'

Same as before, Inner::in_data is not a static member, so you need an
object of class Inner to access that member.
 
D

Dave Townsend

On a slightly different thread, I remember seeing some Microsoft
COM code which played games with nested classes by doing some
pointer arithmetic with "this". My recollection is a
bit fuzzy, but I seem to remember the nested class was able to access
private data in the parent. Is this just pure evil, or is there a standard
compliant way of doing this? It would seem to be a useful mechanism
to break up the functionality of the parent class by using nested classes
each specialized in one particular behavior/functionality.

dave
 
D

Denis Remezov

Dave said:
On a slightly different thread, I remember seeing some Microsoft
COM code which played games with nested classes by doing some
pointer arithmetic with "this". My recollection is a
bit fuzzy, but I seem to remember the nested class was able to access
private data in the parent. Is this just pure evil, or is there a standard
compliant way of doing this? It would seem to be a useful mechanism
to break up the functionality of the parent class by using nested classes
each specialized in one particular behavior/functionality.

I think the OP's thinking was more along the lines of the design:
"objects of nested classes keep a pointer to an object the enclosing
class" (which is the case, e.g., in Java but not in C++).

As regarding access rights of a nested class to members of an enclosing
class, see DR45 (I really welcome it and hope it makes it into the next
revision of the standard):

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#45

Gcc and EDG (not sure about others) already support the proposed new
rule.

Denis
 
F

Francis Glassborow

Dave Townsend said:
On a slightly different thread, I remember seeing some Microsoft
COM code which played games with nested classes by doing some
pointer arithmetic with "this". My recollection is a
bit fuzzy, but I seem to remember the nested class was able to access
private data in the parent.

Well that has always been allowed (till the Standard was published) by
declaring the nested class a friend of the enclosing class) The wording
of the Standard (clearly a defect) actually makes that impossible in a
Standard conforming way. The resolution of the defect by an almost
unanimous vote of those present (a very rare occurrence) was that nested
classes should have full access to their enclosing class.
Is this just pure evil,

Is what pure evil?
or is there a standard
compliant way of doing this?

At the moment, no but in practice yes. Either have a compiler that
accepts the relevant friend declaration or one that accepts the defect
resolution (all C++ compilers do one or the other or both)
 
F

Francis Glassborow

Denis Remezov said:
As regarding access rights of a nested class to members of an enclosing
class, see DR45 (I really welcome it and hope it makes it into the next
revision of the standard):

It will.
 
C

Chris \( Val \)

| newbiecpp wrote:
| > Why this code cannot be compiled (under VC++ 7.0):
| >
| > class Outer {
| > public:
| > class Inner {
| > public:
| > Inner() : in_data(0) {}
| > void action()
| > {
| > Outer::eek:ut_data++; // illegal reference to non-static
| > member 'Outer::eek:ut_data'
| > }
| >
| > int in_data;
| > };
| >
| > Outer() : out_data(0) {}
| > void action()
| > {
| > Inner::in_data++; // ittlegal reference to non-static member
| > 'Outer::Inner::in_data'
| > }
| >
| > int out_data;
| > };
|
| It should not compile on any standard C++ compiler.
|
| In C++, an inner class is just a type definition, you need to
| specifically instantiate an object.
|
| e.g.
| Outer::Inner my_inner_object;
|
| in some funtion
| ...
| ++ my_inner_object.in_data;
| ...
|
| would do what you want.
|
| You can obviously have a member variable in Outer that also instaniates
| the Inner class.
|
| e.g.
| class Outer {
| ....
| Inner m_inner;
| ....
| void func()
| {
| ++ m_inner.in_data;
| }
| };

You could also use the label type syntax:

class Outer
{
private:
class Inner {
// ...
} InnerObject;

public:
// ...
};

....and initialise 'InnerObject' in the initialiser
list of 'Outer'.

Cheers.
Chris Val
 

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
474,175
Messages
2,570,942
Members
47,490
Latest member
Finplus

Latest Threads

Top