2

在 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)”和“for (auto n: a.nodes())”,但这看起来相当难看。

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

4

2 回答 2

3

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

于 2013-09-02T11:38:36.407 回答
1

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

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

当然,除非你告诉它。这将需要存储每个B对象的状态;B必须存储指向A它所属的指针/引用。

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

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

所以“零成本”是不可能的。由于B实例将不得不A占用A.

于 2013-09-02T15:39:55.277 回答