嵌套类对象的所有者

Owner of nested class object

本文关键字:所有者 对象 嵌套      更新时间:2023-10-16

在C++/C++11中,如何获得嵌套类实例化的"所有者"的引用/指针?例如:

class A
{
public:
    friend class B;
    class B
    {
    public:
        Foo bar(int i) { return get_owner().x[...]; }
    private:
        A& get_owner()
        { // How to do this? Pseudo code:
            return (A*)(this - offsetof(A, b));
        }
    };
    B b;
};

注意:在我的例子中,A是而不是标准布局类型,因为它有私有和公共成员变量。

背景:我想为复杂属性实现"零成本"语法糖,这些属性访问所属类中的数据结构,并允许A的用户编写,例如

A a;
...
x = a.nodes[5];
y = a.nodes.size();
for (auto n: a.nodes)  // using a.nodes.begin() and a.nodes.end()
    ...

注2:我可能会使用肮脏的技巧来做到这一点,但有没有一种可移植的、符合标准的方法来做到这
如果没有,我将不得不实现B,这样我就可以写"a.nodes(5)"answers"for(auto n:a.nodes())",但这看起来相当难看。

编辑:我已经考虑过给B一个对a的引用,但后来我不能为a使用默认的复制/移动构造函数/赋值运算符。这在我的情况下不会那么糟糕,但我很好奇是否有其他解决方案。

B添加一个指向所有者的成员。

A的每个实例都有一个类B的成员这一事实B并不知道。

创建从BA的映射的唯一方法是创建一个。你自己不存在这样的映射,因为不是每个B实例都需要与A实例关联。只有作为A的一部分创建的实例才是,B无法知道它是否是A的一部分。

当然,除非你说出来,否则不会。这将需要存储每个B对象的状态;CCD_ 13将必须存储指向它是其成员的CCD_ 14的指针/引用。

背景:我想为复杂属性实现"零成本"语法糖,这些属性访问所属类中的数据结构,并允许A的用户编写,例如

这在C++中是不可能的;最好现在就放弃。即使B为空,也不要求它们不会占用A中的空间。事实上,有一个要求是它们占用A中的空间。类实例的每个成员都有一个地址,并且不允许两个成员具有相同的地址。空基优化仅适用于基类,而不适用于成员。

因此,实现"零成本"是不可能的。由于B实例将不得不占用A中的空间,您还可以通过存储指向A成员的指针/引用来充分利用该空间。