473,395 Members | 1,948 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

inner class accessing outer

Hi folks,

I've got something like:

class Outer {
int f();

friend class Inner;
class Inner {
int g() {
// call f from here
}
}
}
and I want to call Outer::f from inside g. Simply doing Outer::f()
doesn't work, gcc complains it doesn't have an object pointer (which is
somehow bogus, imho -- the compiler could derive a pointer to Outer
because Inner is instantiated within Outer).

Or could I perhaps obtain Outer's this from Inner?

I'm aware of the workaround that involves passing a pointer to the Outer
instance to Inner's constructor. That's what I'd like to avoid.

Thanks.
Nov 26 '07 #1
9 4657
Matthias Buelow wrote:
I've got something like:

class Outer {
int f();

friend class Inner;
I am not sure this is necessary...
class Inner {
int g() {
// call f from here
}
}
}
I believe a few semicolons are missing here...
and I want to call Outer::f from inside g.
On what 'Outer' object? Do you have an 'Outer' object to call 'f'
for? 'f' is non-static, so you need an object of class 'Outer' which
to supply to 'f' as the hidden argument.
Simply doing Outer::f()
doesn't work, gcc complains it doesn't have an object pointer
Correct.
(which
is somehow bogus, imho -- the compiler could derive a pointer to Outer
because Inner is instantiated within Outer).
Who is instantiated inside of whom? 'Inner' _class_ is *declared*
insde the 'Outer' _class_. There is no relationship between them
from the instances POV. C++ is not Java.
Or could I perhaps obtain Outer's this from Inner?
If your 'Inner' keeps a {pointer to|reference to|instance of} Outer,
you can of course "obtain" it from 'this'. Otherwise, you need to
pass the 'Outer' you need as the argument.
I'm aware of the workaround that involves passing a pointer to the
Outer instance to Inner's constructor. That's what I'd like to avoid.
Don't pass it to the constructor. Pass it to 'g'.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 26 '07 #2
Victor Bazarov wrote:
I believe a few semicolons are missing here...
Yes...
Who is instantiated inside of whom? 'Inner' _class_ is *declared*
insde the 'Outer' _class_. There is no relationship between them
from the instances POV. C++ is not Java.
Errm. I posted a bit carelessly. Suppose that:

class Outer {
int f() {}
class Inner {
int g() { /* want to call f here */ }
} inner;
};

Now Outer::Inner::g() could possibly have access to the Outer object, if
the compiler does the Right Thing... but apparently it's not supported
or is it somehow, that's what I want to know.
Nov 26 '07 #3
Victor Bazarov wrote:
but if 'inner' is the only member in 'Outer', it
Yeah, except that it isn't, in my real code.
class SomeOtherOuter {
double a;
char *b;
Outer::Inner myowninner;
};

and call 'g' for 'myowninner'? Yeah, yeah, you can claim that 'Inner'
is private in 'Outer' (what if it isn't?) but I can then say that I
edit the 'Outer' to make 'SomeOtherOuter' a friend... See how easy it
is to bring down that house of cards?
Hmm.. this is indeed a counter-example. However, if an inner class
hypothetically accessed parts of its outer class "directly", the
compiler could flag an error if the inner class would be used anywhere
outside of the outer class it is defined in (or automatically make it
"private" or somesuch).
The only reliable way is to let 'Inner' instance know in what 'Outer'
it is contained. And you already know how to do that. Another way
is _not_ to let 'Inner' know, but pass 'Outer' as the argument to
the 'g()'.
Yeah.. but it's more typing (and hence uglier code..)
Nov 26 '07 #4
Victor Bazarov wrote:
There is no "its outer class". I am guessing you don't get the point
that 'Inner's being declared inside 'Outer' is inconsequential to the
nature of 'Inner'-'Outer' relationship as far as C++ is concerned.
That's not entirely true -- consider the following example:

class Outer {
typedef int T;
public:
class Inner {
T x;
};
};

this could be extended to object relationship (not just types).
That's nonsense. It would limit the use of 'Inner' to inside of the
"outer" class, which is unacceptable;
In this case it would be the behaviour I want; certainly far from
"nonsense".
And 'Inner' cannot know whether
it's declared "private" or not inside the 'Outer'. Heck, 'Inner'
has really no idea that it's declared inside some other scope at
all (not that it's disallowed to gain access to that information,
it just doesn't have any need in most cases).
"Inner" doesn't; but the compiler does.
Nov 26 '07 #5
On Mon, 26 Nov 2007 14:55:56 +0100, Matthias Buelow wrote:
Hi folks,

I've got something like:

class Outer {
int f();

friend class Inner;
class Inner {
int g() {
// call f from here
}
}
}
and I want to call Outer::f from inside g. Simply doing Outer::f()
doesn't work, gcc complains it doesn't have an object pointer (which is
somehow bogus, imho -- the compiler could derive a pointer to Outer
because Inner is instantiated within Outer).

Or could I perhaps obtain Outer's this from Inner?

I'm aware of the workaround that involves passing a pointer to the Outer
instance to Inner's constructor. That's what I'd like to avoid.

Thanks.
First of all - you mistake C++ and Java. C++ inner classes are like
static inner classes in Java - no owning object of outer class, so no
pointer to it. You have to give an Outer object to g somehow (a parameter
to g or a parameter to Inner constructor).
Second:
friend class Inner;
is a way to let functions of class Inner access private members of class
Outer (good idea as f seems to be private). But you must put this line
after definition of class Inner. Otherwise the compiler will assume you
are referring to a class defined somewhere outside the class Outer not
the class you intended.

HTH
--
Tadeusz B. Kopec (tk****@NOSPAMPLEASElife.pl)
Ahead warp factor one, Mr. Sulu.
Nov 26 '07 #6
Matthias Buelow wrote:
Victor Bazarov wrote:
>There is no "its outer class". I am guessing you don't get the point
that 'Inner's being declared inside 'Outer' is inconsequential to the
nature of 'Inner'-'Outer' relationship as far as C++ is concerned.

That's not entirely true -- consider the following example:

class Outer {
typedef int T;
public:
class Inner {
T x;
};
};

this could be extended to object relationship (not just types).
I wonder how. Instances don't have scopes. Members don't exist
without instances. Here, you have 'T' which is a name that can be
looked up at the compilation time, and the scope of 'Outer::Inner'
has a very specific set of rules for name lookup.

Now, remove they 'typedef' (to make 'T' an instance). What do you
have?

class Outer {
int T;
public:
class Inner {
void foo() { T = 42; }
};
};

You have 'T' that is an instance of 'int', but it doesn't exist
in a vacuum. It only exists in an instance of 'Outer'. The
compiler has no idea where that instance of 'Outer' is. No clue
whatsoever. What do you propose? Let's rehearse the conversation
you're going to have in 'comp.std.c++' (see my suggestion below).

You're saying that if you declare an instance of 'inner' inside
an instance of 'Outer', the compiler has to know how to get the
address of one and convert it to the address of the other. How?
What if it doesn't exist?

class Outer {
int T;

class Inner {
void foo() { T = 42; }
} inner;

void bar();
};

void Outer::bar() {
Inner i;
i.foo(); // now what?! Whose 'T' are we changing now?
}

Are you going to prohibit the use of 'Inner' like that? Fine,
somehow 'Inner' is private (as I made it in my last example), but
it should also become incomplete class (so you cannot instantiate
it as a stand-alone object even inside 'Outer' scope)? Then how
do we instantiate the 'Outer::inner' member? See the conflict?
Or do we simply allow 'i' inside 'Outer::bar' to change 'this->T'
somehow?

Think about all possible variations of the use of 'Inner' and not
just how _you_ want to use it. I believe the expression is "to
see beyond one's nose".
>That's nonsense. It would limit the use of 'Inner' to inside of the
"outer" class, which is unacceptable;

In this case it would be the behaviour I want; certainly far from
"nonsense".
But you seem to want to have this behaviour as the norm. It's not
because it cannot be. It just wouldn't make sense as the norm.

It's impossible to make everybody happy, that's true. That's why
the langauges are usually designed to make the majority of people
happy and if a few unhappy people remain, they usually get to use
the work-arounds.
>And 'Inner' cannot know whether
it's declared "private" or not inside the 'Outer'. Heck, 'Inner'
has really no idea that it's declared inside some other scope at
all (not that it's disallowed to gain access to that information,
it just doesn't have any need in most cases).

"Inner" doesn't; but the compiler does.
So? The compiler knows many other things. Every compiler knows
its own set of things, AAMOF. If you need to be able to know the
things the compiler knows, turn to the compiler's manual. If you
want to make what compiler knows available to the programmer and
specify that in the Standard, then it's a different story.

I believe you're arguing a change in the language. I don't think
this is the right newsgroup for it. Try 'comp.std.c++'. Explain
what you think is missing from the language, make a proposal. Do
not forget to have a business case (what problem it solves that
cannot be solved otherwise). Then present your argument and have
the language changed. Or have your mind changed for the work-
around that you're "trying to avoid". Either way, 'comp.std.c++'
is _the_ newsgroup for trying to get your point across to the
people who are on the bleeding edge of making C++ work better.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 26 '07 #7
Victor Bazarov wrote:
I wonder how. Instances don't have scopes. Members don't exist
without instances. Here, you have 'T' which is a name that can be
Well.. one could use lexical scope. This would break the homology with
C, where struct X { struct Y {...}; }; makes struct Y visible within the
whole compilation unit but well.
class Outer {
int T;

class Inner {
void foo() { T = 42; }
} inner;

void bar();
};

void Outer::bar() {
Inner i;
i.foo(); // now what?! Whose 'T' are we changing now?
}
Or do we simply allow 'i' inside 'Outer::bar' to change 'this->T'
somehow?
Well, I see the problem. Changing it to mean "this->T" in this case
would be the most obvious solution, imho. Actually, I think that would
be quite neat but perhaps not fit entirely into the C++ mindframe...
Think about all possible variations of the use of 'Inner' and not
just how _you_ want to use it. I believe the expression is "to
see beyond one's nose".
This could be made even more powerful, like treating T (in this example)
somewhat akin to a free variable and binding it to the (lexically)
surrounding binding, for example:

void Outer::bar() {
int T;
Inner i;
i.foo(); // would refer to T in bar()'s scope
}

This could be resolved at compile-time.

Of course, the next problem would be:

void Outer::bar() {
int T;
Inner *i = new Inner;
i->foo(); // now what?
}

I don't think it's a real show-stopper but I'm not into going into this
now.
I believe you're arguing a change in the language. I don't think
this is the right newsgroup for it. Try 'comp.std.c++'. Explain
I don't really want to; I just didn't know if there wasn't perhaps some
way to have an "inner" class access members of a surrounding class.
Nov 26 '07 #8
On Nov 26, 3:58 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Matthias Buelow wrote:
I've got something like:
class Outer {
int f();
friend class Inner;
I am not sure this is necessary...
It depends on the version of the standard his compiler
implements. It's probably a good idea, but it almost definitly
should go *after* the definition (or at least a declaration) of
Inner; if it's before, as here, it says that there is some class
named Inner in the enclosing namespace which is a friend.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nov 27 '07 #9
Matthias Buelow wrote:
Hi folks,

I've got something like:

class Outer {
int f();

friend class Inner;
class Inner {
int g() {
// call f from here
}
}
}
and I want to call Outer::f from inside g. Simply doing Outer::f()
doesn't work, gcc complains it doesn't have an object pointer (which is
somehow bogus, imho -- the compiler could derive a pointer to Outer
because Inner is instantiated within Outer).

Or could I perhaps obtain Outer's this from Inner?

I'm aware of the workaround that involves passing a pointer to the Outer
instance to Inner's constructor. That's what I'd like to avoid.
According to the current standard, it's necessary to declaration nested
class friend.
IIRC, VC does NOT need the friend declaration.

Anyway, your way of declaring nested class a friend is wrong.

class Outter
{
class Inner
{
};
friend class Inner;
};

or

class Outter
{
class Inner; // needed, or else,
friend class Inner; // Inner is a friend from the enclosing namespace

class Inner
{
};
};
Nov 27 '07 #10

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

Similar topics

2
by: Murat Tasan | last post by:
i have an inner class and an outer class, both of which have an identically named member. how from the inner class can i reference the outer member? (the example code should illustrate this...
3
by: trialproduct2004 | last post by:
hi all i am having application which is using two classes. in one class i am creating instance of another class and calling method of that class. what i want is from inner class's method i want...
9
by: Joel Moore | last post by:
I'm a little confused here. If I have the following: Public ClassA Friend varA As Integer Private varB As Integer Private ClassB Public Sub MethodA() ' How can I access varA and varB here?...
9
by: MariusI | last post by:
Consider the following class layout public class Order { public ProductOrder AddProductOrder(/* variables required to create a product order */) { /* Check if the product order can be added...
4
by: amaca | last post by:
In this slightly contrived (though small, complete and perfectly formed) example: public class Inner { public event EventHandler InnerHandler; public void DoSomething() { if ( InnerHandler...
1
by: bob | last post by:
what's the difference between inner join and outer join in sql?
5
by: Martijn Mulder | last post by:
A construction like this: class Outer { class Inner:Outer { } } compiles without problem but does it introduce infinity?
1
by: mrstephengross | last post by:
I'm making progress on mixing templates with friends (sounds like a drinking game, huh?). Anyway, here's the situation. I've got an "Outer" class with a private "Inner" class (sub-class,...
0
by: pramodhts | last post by:
how to implement inner outer classes in c# i have two nested classes like class Outer { int TestVariable = 0; class Inner
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
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,...
0
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...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
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...
0
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...
0
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,...

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.