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

时间:2018-06-10 04:58:51

标签: c++ oop

问题

我在Java上看到THIS问题,它允许您从嵌套对象中获取指向外部对象的指针。

但你怎么能在 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 个答案:

答案 0 :(得分:1)

这是保存一些空间的一个想法:

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;
    }
};

如果您使用的是具有32位整数的64位计算机,则会将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(或某些哨兵值)。< / p>