代码之家  ›  专栏  ›  技术社区  ›  Kostas

在C++中从内部类对象获取外部类对象

  •  -1
  • Kostas  · 技术社区  · 7 年前

    问题

    我看见了 THIS Java中的问题,它允许您获得指向 外部对象 从一个 嵌套对象 .

    但是你怎么能在 C++ ?

    不满意的解决方案:

    存储指向每个对象的指针 :(不节省内存)

    class Outer {
    private:
        int i;
        class Inner {
            int j;
            Outer *outer;
        };
        Inner items[1000];
    };
    

    在类中包装数组 :(添加不必要的(?)复杂性)

    class Outer {
    private:
        int i;
        class Inner_array {
            class Inner {
                int j;
            };
            Inner items[1000];
    
            // Build an interface around the array
            typedef Inner (&array)[1000]; 
            operator array();
            // etc...
        };
    
        Inner items[1000];
        Outer *outer;
    };
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   John Zwinck    7 年前

    以下是一个节省空间的方法:

    struct Outer {
        int i;
    
        struct Inner {
            int j;
            uint16_t where;
    
            Outer& outer() {
                Inner* first = this - where;
                char* addr = reinterpret_cast<char*>(first) - offsetof(Outer, items);
                return *reinterpret_cast<Outer*>(addr);
            }
        };
    
        Inner items[1000];
    
        Outer() {
            for (uint16_t ii = 0; ii < 1000; ++ii)
                items[ii].where = ii;
        }
    };
    

    如果您在一台64位计算机上使用32位整数,那么 sizeof(Inner) 从16到8字节(不打包)或12到6字节(打包)。

    如果要节省更多空间,可以执行以下操作:

    struct Outer {
        int i;
    
        struct Inner {
            int j;
    
            Outer& outer() {
                Inner* sentinel = this;
                while (sentinel.j != INT_MIN)
                    --sentinel;
                char* addr = reinterpret_cast<char*>(sentinel) - offsetof(Outer, sentinel);
                return *reinterpret_cast<Outer*>(addr);
            }
        };
    
        Inner sentinel = {INT_MIN};
        Inner items[1000];
    };
    

    但是然后 outer() 是o(n)而不是o(1),您必须确保 INT_MIN (或某些哨兵值)从未用于 items