How to refer to enclosing instance from C++ inner

2020-02-01 04:14发布

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.

7条回答
霸刀☆藐视天下
2楼-- · 2020-02-01 04:35

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楼-- · 2020-02-01 04:36

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.

查看更多
混吃等死
4楼-- · 2020-02-01 04:41

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/

查看更多
Bombasti
5楼-- · 2020-02-01 04:45

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;
    };
}; 
查看更多
太酷不给撩
6楼-- · 2020-02-01 04:54

There is no implicitly created instance of the enclosing class when creating an instance of the nested class. It has to be done manually.

查看更多
地球回转人心会变
7楼-- · 2020-02-01 04:56

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.

查看更多
登录 后发表回答