在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 不是standard layout type,因为它有私有和公共成员变量。
背景:我想为复杂属性实现“零成本”语法糖,它可以访问拥有类中的数据结构,并允许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的默认复制/移动构造函数/赋值运算符。这在我的情况下不会那么糟糕,但我是好奇是否有另一种解决方案。
答案 0 :(得分:3)
将成员添加到指向所有者的B
。
答案 1 :(得分:1)
类A
的每个实例都具有类B
的成员这一事实不是类B
所知道的。
创建从B
到A
的映射的唯一方法是创建一个。你自己。不存在此类映射,因为并非每个B
实例都必需与A
实例关联。只有那些作为A
的一部分创建的实例才有,B
无法知道它是A
的一部分。
当然,除非你说出来。这将需要存储per - B
- 对象状态; B
必须存储指向它所属的A
的指针/引用。
背景:我想为复杂属性实现“零成本”语法糖,它可以访问拥有类中的数据结构,并允许A的用户写入,例如,
这在C ++中是不可能的;现在最好放弃它。即使B
为空,也不要求他们不占用A
中的空格。实际上,要求他们将占用A
中的空间。类实例的每个成员都有一个地址,并且不允许两个成员拥有相同的地址。 empty-base-optimization仅适用于基类,而不适用于成员。
因此,“零成本”是不可能的。由于B
实例将不得不占用A
中的空间,因此您可以通过将指针/引用存储到A
的成员来充分利用该空间。