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

Definig a Class within a Class

P: n/a
This is probably very easy to answer but for me its new.
Yesterday I realized the need to be able to define a class within another
one. So I have written some test code and its almost syntax error free.

My first goal is to count the Outer classes with a global variable, which
works fine

But then I want to count the Inner classes within the Outer class.
The Varibale innernum is global in repsect to the Class Inner, but
I dont know how to access it.
The error I am getting is
class.cpp: In constructor `Outer::Inner::Inner()':
class.cpp:48: error: type `Outer' is not a base type for type `Outer::Inner'

Its commented in the testcode below. If somebode could show me the right
syntax, I would be happy.
rds
#include <stdio.h>

int outernum=0;

class Outer
{
public:

Outer(void);
~Outer();
void test(void);
int innernum;

class Inner
{
public:

Inner(void);
~Inner();
};
};

Outer::Outer(void)
{
printf("Outer::Outer\n");
innernum=0;
outernum++;
printf("outernum=%d\n",outernum);
}

Outer::~Outer()
{
printf("Outer::~Outer\n");
outernum--;
printf("outernum=%d\n",outernum);
}

void Outer::test(void)
{
printf("Outer::test\n");
Inner a;
Inner b;
}

Outer::Inner::Inner(void)
{
printf("Outer::Inner::Inner\n");
// Outer::innernum++;
// printf("innernum=%d\n",Outer::innernum);
}

Outer::Inner::~Inner()
{
printf("Outer::Inner::~Inner\n");
// Outer::innernum--;
// printf("innernum=%d\n",Outer::innernum);
}

int main(void)
{
Outer a;
Outer b;
a.test();
return 0;
}
Jul 19 '05 #1
Share this Question
Share on Google+
15 Replies


P: n/a

"Guenther Sohler" <gu*************@newlogic.at> wrote in message
news:pa****************************@newlogic.at...
This is probably very easy to answer but for me its new.
Yesterday I realized the need to be able to define a class within another
one. So I have written some test code and its almost syntax error free.

My first goal is to count the Outer classes with a global variable, which
works fine

But then I want to count the Inner classes within the Outer class.
The Varibale innernum is global in repsect to the Class Inner, but
I dont know how to access it.
The error I am getting is
class.cpp: In constructor `Outer::Inner::Inner()':
class.cpp:48: error: type `Outer' is not a base type for type `Outer::Inner'
Its commented in the testcode below. If somebode could show me the right
syntax, I would be happy.
rds
#include <stdio.h>

int outernum=0;

class Outer
{
public:

Outer(void);
~Outer();
void test(void);
int innernum;

class Inner
{
public:

Inner(void);
~Inner();
};
};

Outer::Outer(void)
{
printf("Outer::Outer\n");
innernum=0;
outernum++;
printf("outernum=%d\n",outernum);
}

Outer::~Outer()
{
printf("Outer::~Outer\n");
outernum--;
printf("outernum=%d\n",outernum);
}

void Outer::test(void)
{
printf("Outer::test\n");
Inner a;
Inner b;
}

Outer::Inner::Inner(void)
{
printf("Outer::Inner::Inner\n");
// Outer::innernum++;
// printf("innernum=%d\n",Outer::innernum);
}

Outer::Inner::~Inner()
{
printf("Outer::Inner::~Inner\n");
// Outer::innernum--;
// printf("innernum=%d\n",Outer::innernum);
}

int main(void)
{
Outer a;
Outer b;
a.test();
return 0;
}


Your code is correct, your compiler is broken. Get a better compiler.

john
Jul 19 '05 #2

P: n/a
John Harrison wrote:
[SNIP]
Your code is correct, your compiler is broken. Get a better compiler.


False. Inner classes have no special access to the outer class in C++.

Attila aka WW
Jul 19 '05 #3

P: n/a
Guenther Sohler <gu*************@newlogic.at> wrote in
news:pa****************************@newlogic.at:
This is probably very easy to answer but for me its new.
Yesterday I realized the need to be able to define a class within
another one. So I have written some test code and its almost syntax
error free.

My first goal is to count the Outer classes with a global variable,
which works fine

But then I want to count the Inner classes within the Outer class.
The Varibale innernum is global in repsect to the Class Inner, but
I dont know how to access it.
The error I am getting is
class.cpp: In constructor `Outer::Inner::Inner()':
class.cpp:48: error: type `Outer' is not a base type for type
`Outer::Inner'

You cannot access any nonstatic member of Outer inside Inner. Because:
your Inner class is inside the namespace of Outer, but that's all. Any
Inner is not bound to any Outer, so there the Outer object carrying the
count variable does not need to be present and is not accessible via
Inner.

If you want to access any Outer nonstatic data members you need an
Outer*this pointer to modify them.

Just keep in mind that the following also is legal:

//your classes snipped.

//at global scope:

Outer::Inner inner_class; //legal, Inner is public in Outer.

I think what you actually were looking for is factory pattern, so that
any Inner has an outbound Outer class.
Jul 19 '05 #4

P: n/a

"Attila Feher" <at**********@lmf.ericsson.se> wrote in message
news:bh**********@newstree.wise.edt.ericsson.se...
John Harrison wrote:
[SNIP]
Your code is correct, your compiler is broken. Get a better compiler.


False. Inner classes have no special access to the outer class in C++.

Attila aka WW


I know, but the OP claimed the code was causing compile errors. I compiled
his code on two different compilers without errors. Are you saying that the
code posted shouldn't compile?

john
Jul 19 '05 #5

P: n/a

"John Harrison" <jo*************@hotmail.com> wrote in message
news:bh************@ID-196037.news.uni-berlin.de...

"Attila Feher" <at**********@lmf.ericsson.se> wrote in message
news:bh**********@newstree.wise.edt.ericsson.se...
John Harrison wrote:
[SNIP]
Your code is correct, your compiler is broken. Get a better compiler.
False. Inner classes have no special access to the outer class in C++.

Attila aka WW


I know, but the OP claimed the code was causing compile errors. I compiled
his code on two different compilers without errors. Are you saying that

the code posted shouldn't compile?


OK my mistake, I didn't realise the OP had commented out the troublesome
lines.

To the OP, its not a good idea to comment out the lines you are having
trouble with. People like me will just cut and paste your code without
realising they have to alter it first.

john
Jul 19 '05 #6

P: n/a

"John Harrison" <jo*************@hotmail.com> wrote in message
news:bh************@ID-196037.news.uni-berlin.de...

"Attila Feher" <at**********@lmf.ericsson.se> wrote in message
news:bh**********@newstree.wise.edt.ericsson.se...
John Harrison wrote:
[SNIP]
Your code is correct, your compiler is broken. Get a better compiler.
False. Inner classes have no special access to the outer class in C++.

Attila aka WW


I know, but the OP claimed the code was causing compile errors. I compiled
his code on two different compilers without errors. Are you saying that

the code posted shouldn't compile?

OP said that the offending lines had been commented out.
The code should not compile as inner classes have no special access to outer
classes as pointed by Attila.
Jul 19 '05 #7

P: n/a
Josephine Schafer wrote:
[SNIP]
OP said that the offending lines had been commented out.
The code should not compile as inner classes have no special access
to outer classes as pointed by Attila.


In addition to that (IIRC) you canot even make them friends. I do not
recall if it was making inner the friend of outer or vica versa... But the
point was is that the class has not been defined yet at the point where you
want to make it a friend. So the language is actually going to change to
allow access (friendship) by default. I am so dumb nowadays that I do not
recall exactly what was said in Oxford. :-(

--
Attila aka WW
Jul 19 '05 #8

P: n/a
On Tue, 19 Aug 2003 15:35:00 +0300, Attila Feher wrote:
In addition to that (IIRC) you canot even make them friends. I do not
recall if it was making inner the friend of outer or vica versa... But the
point was is that the class has not been defined yet


Wouldn't a declaration of the classes first fix that?

regards
NPV
Jul 19 '05 #9

P: n/a
"Guenther Sohler" <gu*************@newlogic.at> wrote in message
news:pa****************************@newlogic.at...
| This is probably very easy to answer but for me its new.
| Yesterday I realized the need to be able to define a class within another
| one. So I have written some test code and its almost syntax error free.
|
| My first goal is to count the Outer classes with a global variable, which
| works fine
|
| But then I want to count the Inner classes within the Outer class.
| The Varibale innernum is global in repsect to the Class Inner, but
| I dont know how to access it.

Here's a way to do it:

class Inner {
public:
Inner(Outer& owner) : owner_(owner) { ++owner_.innernum; }
~Inner(Outer& owner) { --owner_.innernum; }

private:
Outer& owner_;
};

Be careful that all 'Inner' instanced attached to an instance of Outer
are destroyed before the 'Outer' instance.
You may want to check this with an assert in Outer::~Outer:
assert( this->innernum == 0 );
hth,
--
Ivan Vecerina <> http://www.post1.com/~ivec
Brainbench MVP for C++ <> http://www.brainbench.com
Jul 19 '05 #10

P: n/a
Thank you for the many answers.

OK. Next time i will not comment it anymore.
I just commented it because I thought it was completely wrong.
It was jsut meant to be a comment for that which should go there.
Outer::Inner inner_class; //legal, Inner is public in Outer.

I think what you actually were looking for is factory pattern, so that
any Inner has an outbound Outer class.

Yes, sounds like that I want.
But I dont want to care for an outer pointer. Cant this link be done
automatically ?
Inner is always called within a Outer class. And so the link information
is given.
Actually this is just a test to test the capabilities of hierarchical
classes.
If my Attempt works, I will extend all that to a bigger database/handle
issue.
The Varibale inenrnum will become a database within System,
and Inner will become a Handle class.
The big advantage of the Inner class in contrast to just a int as
handlenum
is that I can define constructor and destructor code, which is important
for the functionality of the whole system.
So I dont have to do it manually. every time.

Did anybody understand my intention ?

rds
Jul 19 '05 #11

P: n/a
"Nils Petter Vaskinn" <no@spam.for.me.invalid> wrote in
news:pa****************************@spam.for.me.in valid:
On Tue, 19 Aug 2003 15:35:00 +0300, Attila Feher wrote:
In addition to that (IIRC) you canot even make them friends. I do
not recall if it was making inner the friend of outer or vica
versa... But the point was is that the class has not been defined
yet


Wouldn't a declaration of the classes first fix that?


Of course that will. A class doesn't need to be defined when making
friends, but known.

namespace test {
class Outer;

class Outer
{
class Inner {

friend class ::test::Outer;

};

friend class Inner;
};

}
--
http://xrxixpx.rip-productions.de
Jul 19 '05 #12

P: n/a
GS> If somebode could show me the right
GS> syntax, I would be happy.

Does this what you want?

#include <iostream>
int number=0;
class Outer
{
public:int number;
public:Outer():number(0){++::number;new Inner(this);show();}
public:virtual~Outer(){--::number;show();}
public:void test(){Inner a(this),b(this);show();}
public:void show()
{
std::cout<<"\nNumber of Outers: "<<::number;
std::cout<<"\tNumber of Inners: "<<number;
}
class Inner
{
public:Inner(Outer*a):outer(a){++outer->number;outer->show();}
public:virtual~Inner(){--outer->number;outer->show();}
private:Outer*outer;
};};
int main(int argc,char**argv)
{
Outer a,b,c;
a.test();
return 0;
}
_______
output:
Number of Outers: 1 Number of Inners: 1
Number of Outers: 1 Number of Inners: 1
Number of Outers: 2 Number of Inners: 1
Number of Outers: 2 Number of Inners: 1
Number of Outers: 3 Number of Inners: 1
Number of Outers: 3 Number of Inners: 1
Number of Outers: 3 Number of Inners: 2
Number of Outers: 3 Number of Inners: 3
Number of Outers: 3 Number of Inners: 3
Number of Outers: 3 Number of Inners: 2
Number of Outers: 3 Number of Inners: 1
Number of Outers: 2 Number of Inners: 1
Number of Outers: 1 Number of Inners: 1
Number of Outers: 0 Number of Inners: 1

Jul 19 '05 #13

P: n/a
Immanuel Albrecht wrote:
Immanuel Albrecht <xr*****@gmx.de> wrote in
news:bh*************@news.t- online.com:
"Nils Petter Vaskinn" <no@spam.for.me.invalid> wrote in
news:pa****************************@spam.for.me.in valid:
On Tue, 19 Aug 2003 15:35:00 +0300, Attila Feher wrote:

In addition to that (IIRC) you canot even make them friends. I do
not recall if it was making inner the friend of outer or vica
versa... But the point was is that the class has not been defined
yet

Wouldn't a declaration of the classes first fix that?


Of course that will. A class doesn't need to be defined when making
friends, but known.


Correction. It must not be known. Even friend class Grandma would
work.


Wrong. Ask Herb Sutter or anyone involved in C++ standardization. Current
compilers do it wrong on purpose - otherwise nothing would work.

First error (IMHO this is an old one, not what I am talkign about):

http://anubis.dkuug.dk/jtc1/sc22/wg2...efects.html#77


Jul 19 '05 #14

P: n/a
Guenther Sohler wrote:
Thank you for the many answers.

OK. Next time i will not comment it anymore.
I just commented it because I thought it was completely wrong.
It was jsut meant to be a comment for that which should go there.
Outer::Inner inner_class; //legal, Inner is public in Outer.

I think what you actually were looking for is factory pattern, so
that any Inner has an outbound Outer class. Yes, sounds like that I want.
But I dont want to care for an outer pointer. Cant this link be done
automatically ?
Inner is always called within a Outer class. And so the link
information is given.
Actually this is just a test to test the capabilities of hierarchical
classes.
If my Attempt works, I will extend all that to a bigger
database/handle issue.
The Varibale inenrnum will become a database within System,
and Inner will become a Handle class.
The big advantage of the Inner class in contrast to just a int as
handlenum
is that I can define constructor and destructor code, which is
important for the functionality of the whole system.
So I dont have to do it manually. every time.

You don't need nested classe *definitions* to do this.

Did anybody understand my intention ?


Probably, but why use a nested class definition in the first place? Just
define the inner class as any other normal class on its todd. There is
no reason to be more complicated than need be. The fact that you have
actually posted this question suggests to me that you don't have enough,
with all due respect, knowledge to evaluate why you think this method is
a better way. Unless you can *solidly* back up *why* you want to nest
classes, don't do it. By and large, all a nested class is going to do is
allow you to use that same lexical name for something else!
Kevin Aylward
sa**********@anasoft.co.uk
http://www.anasoft.co.uk
SuperSpice, a very affordable Mixed-Mode
Windows Simulator with Schematic Capture,
Waveform Display, FFT's and Filter Design.
Jul 19 '05 #15

P: n/a
Thank you very much for that idea,

but in that case I could simplify the problem by just defining inner and
Outer next to each other, not inside.
This would also work.

Would it ?
#include <stdio.h>

int outernum=0;

class Outer
{
public:

Outer(void);
~Outer();
void test(void);
int innernum;

class Inner
{
public:

Inner(Outer& myOuter);
~Inner();
Outer& myOuter;
};
};

Outer::Outer(void)
{
printf("Outer::Outer\n");
innernum=0;
outernum++;
printf("outernum=%d\n",outernum);
}

Outer::~Outer()
{
printf("Outer::~Outer\n");
outernum--;
printf("outernum=%d\n",outernum);
}

void Outer::test(void)
{
printf("Outer::test\n");
Inner a(*this);
Inner b(*this);
}

Outer::Inner::Inner(Outer& myOuter):
myOuter(myOuter)
{
printf("Outer::Inner::Inner\n");
myOuter.innernum++;
printf("innernum=%d\n", myOuter.innernum);
}

Outer::Inner::~Inner()
{
printf("Outer::Inner::~Inner\n");
myOuter.innernum--;
printf("innernum=%d\n",myOuter.innernum);
}

int main(void)
{
Outer a;
Outer b;
a.test();
return 0;
}

---

Here's the output:

Outer::Outer
outernum=1
Outer::Outer
outernum=2
Outer::test
Outer::Inner::Inner
innernum=1
Outer::Inner::Inner
innernum=2
Outer::Inner::~Inner
innernum=1
Outer::Inner::~Inner
innernum=0
Outer::~Outer
outernum=1
Outer::~Outer
outernum=0


Jul 23 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.