c ++使用"菱形"继承语法访问基类成员

Tim*_*eus 2 c++

假设,我想创建一个类如下,不使用虚拟继承.从"lower"实例访问"upper"类的成员的语法是什么?已经有一些左,右的方法,但不确定哪个是"规范"正确的.如何访问成员更低---上方?

/*       upper
        /  |  \
     left  |  right
        \  |  /
         lower
*/

class upper {
public:
int base;};

class left : public upper  {};

class right : public upper {};

class lower : public right, public left, public upper {};

int main(){

lower a;

// a.base=1;        // error: request for member 'base' is ambiguous
// a.upper::left::lower::base=1;    // error: 'upper::left' has not been declared
// a.lower::left::upper::base=2;    // error: 'upper' is an ambiguous base of 'lower'
// a.left::upper::base=1;           // error: 'upper' is an ambiguous base of 'lower'

// a.lower::upper::base=1;  // error: 'upper' is an ambiguous base of 'lower'
// a.upper::lower::base=1   // error: 'upper::lower' has not been declared

a.lower::left::base=1;  // works
a.right::base=1;        // works

return 0;}
Run Code Online (Sandbox Code Playgroud)

谢谢.

PS我已经读过使用它的危险.:)

Swi*_*Pie 5

这不是钻石计划,这是一个"被诅咒的钻石".继承菱形没有从基类到大多数派生类的直接行.upper由于模糊的继承,您无法以任何方式访问.你已经在两个"侧翼"类中有两个上层实例.

有些人可能会这样想

a.lower::upper::base = 1; 
Run Code Online (Sandbox Code Playgroud)

应该管用.它不应该.lower为命名空间包含两个upper从s leftright一个来自自己的声明.虽然你可以为指定的命名空间upperleftright,你不能这样做,因为在这样的父母直接"第三轮".就像你试图这样做一样:

/*       upper
        /     \
     left     right
        \     /
         lower
*/

a.upper::base = 1; 
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可以使其工作,但这种架构方法是值得怀疑的.因为它提出了一个问题,如果你真的迫切需要组件 - 实体模式.

/*       upper
        /  |  \
   left center right
        \  |  /
         lower
*/
Run Code Online (Sandbox Code Playgroud)

换句话说:虽然有两个以上的父母在关系中为了祖父母能够到达它的孙子是有趣的,在实践中细菌与他们的质粒已经找到了更好的方法.