c++c++11nested-classoffsetofouter-classes

Have C++11 some portable and effective way to access enclosing class from nested class?


What I am needing can be done by storing this pointer of enclosing class into nested class for example this way:

class CEnclosing {
public:
    class CNested : public CSomeGeneric {
    public: 
        CNested(CEnclosing* e) : m_e(e) {}
        virtual void operator=(int i) { m_e->SomeMethod(i); }
        CEnclosing* m_e;
    };

    CNested nested;

    CEnclosing() : nested(this) {}

    virtual void SomeMethod(int i);
};


int main() 
{
    CEnclosing e;
    e.nested = 123;
    return 0;
}

This works well, but requires sizeof(void*) bytes of memory more for each nested member class. Exist effective and portable way to do this without need to store pointer to instance of CEnclosing in m_e?


Solution

  • As stated previously, C++ does not provide any way to do this. A nested class has no special way to find its enclosing class. The solution you already have is the recommended way.

    If you have an advanced scenario, and if you are prepared to maintain non-portable code, and if the cost of storing an additional pointer is important enough to use a risky solution, then there is a way based on the C++ object model. With a number of provisos I won't go into, you can rely on the enclosing and nested classes being laid out in memory in a predictable order, and there being a fixed offset between the start of the enclosing and nested classes.

    The code is something like:

       CEnclosing e;
       int offset = (char*)&e.nested - (char*)&e;
       //... inside nested class
       CEnclosing* pencl = (CEnclosing*)((char*)this - offset);
    

    OTOH it's equally possible that the offsetof macro may just do it for you, but I haven't tried it.

    If you really want to do this, read about trivially copyable and standard layout in the standard.