可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
In C++, an object refers to itself via this
.
But how does an instance of an inner class refer to the instance of its enclosing class?
class Zoo
{
class Bear
{
void runAway()
{
EscapeService::helpEscapeFrom (
this, /* the Bear */
??? /* I need a pointer to the Bear's Zoo here */);
}
};
};
EDIT
My understanding of how non-static inner classes work is that Bear
can access the members of its Zoo
, therefore it has an implicit pointer to Zoo
. I don't want to access the members in this case; I'm trying to get that implicit pointer.
回答1:
Unlike Java, inner classes in C++ do not have an implicit reference to an instance of their enclosing class.
You can simulate this by passing an instance, there are two ways :
pass to the method :
class Zoo
{
class Bear
{
void runAway( Zoo & zoo)
{
EscapeService::helpEscapeFrom (
this, /* the Bear */
zoo );
}
};
};
pass to the constructor :
class Zoo
{
class Bear
{
Bear( Zoo & zoo_ ) : zoo( zoo_ ) {}
void runAway()
{
EscapeService::helpEscapeFrom (
this, /* the Bear */
zoo );
}
Zoo & zoo;
};
};
回答2:
Inner classes are not special, and don't have any link to their outer class built-in. If you want to access the outer class, then pass a pointer or reference, just as you would with any other class.
回答3:
An inner class has access to all members of the outer class, but it does not have an implicit reference to a parent class instance.
To answer your modifed Q:
No you cannot access that implicit pointer. I believe one can do so in Java but not in C++.
You will have to pass the outer class object explicitly through constructor or some other function to acheive this.
Technically as per C++03 standard(sec 11.8.1), a nested class does NOT have special access to its enclosing class.
But there is also this standard defect: openstd.org/jtc1/sc22/wg21/docs/cwg_defects.html#45 Not sure if this is closed.
回答4:
You can access the outer class instance from an inner class instance by using offsetof.
This has zero overhead compared to the pointer/reference solution.
It's a bit dirty but it gets the job done.
For example:
#include <cstddef>
struct enclosing {
struct inner {
enclosing& get_enclosing() {
return *(enclosing*)((char*)this - offsetof(enclosing, i));
}
void printX() {
std::cout << get_enclosing().x << '\n';
}
} i;
int x;
};
int main() {
enclosing e;
e.x = 5;
e.i.printX();
}
P.S.
offsetof makes some assumptions about the type. In C++98 the type has to be a POD and in C++11 the type has to be "standard layout".
Here's a reference: http://www.cplusplus.com/reference/cstddef/offsetof/
回答5:
There is no built-in mechanism to achieve this. You need to provide the pointer yourself, via constructor or some kind of SetParent function.
回答6:
The C++ Standard says (section 11.8.1 [class.access.nest]):
The members of a nested class have no
special access to members of an
enclosing class, nor to classes or
functions that have granted friendship
to an enclosing class; the usual
access rules (clause 11) shall be
obeyed. The members of an enclosing
class have no special access to
members of a nested class; the usual
access rules (clause 11) shall be
obeyed.
(emphasis by me).
This means that there is no special relationship between the nested and enclosing class.
回答7:
There is no implicitly created instance of the enclosing class when creating an instance of the nested class. It has to be done manually.