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

标签 c++

假设,我想创建一个如下所示的类并且不使用虚拟继承。 从“下层”实例访问“上层”类成员的语法是什么? 已经为左和右计算了一些方法,但不确定哪个是“规范”正确的。以及如何访问成员下---上层的方式?

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

谢谢。

附言我已经阅读了使用它的危险。 :)

最佳答案

这不是钻石计划,这是“被诅咒的钻石”。继承菱形没有从基类到大多数派生类的直线。由于继承不明确,您无法以任何方式访问 upper。并且您已经在两个“侧翼”类中获得了 upper inside 的两个实例。

有些人可能认为

a.lower::upper::base = 1; 

应该可以。它不应该。 lower 作为命名空间包含来自 leftright 的两个 upper 和一个来自它自己的声明。虽然您可以为 leftright 内的 upper 指定 namespace ,但您不能为直接的“第三轮”这样做为人 parent 。这就像您尝试这样做一样:

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

a.upper::base = 1; 

在这种情况下,您可以让它发挥作用,但这种架构方法值得商榷。因为它提出了一个问题,即您是否真的急需组件实体模式。

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

换句话说:虽然为了祖 parent 能够接触到孙子而有两个以上的 parent 关系很有趣,但在实践中,带有质粒的细菌找到了更好的方法。

关于c++使用 "diamond"继承语法访问基类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50088703/

相关文章:

c++ - float vs unorm 0->1,哪个更精确?

c++ - 需要一个使用 dht_put_item 和 libtorrent 的例子

c++ - 由于 sizeof() 无法输出 int

c++ - 在 C++ 中更改整个结构的字节顺序

c# - 在 C# 委托(delegate)中编码 va_list

c++ - windows.h 和限制的冲突?

c++ - C++中的构造函数调用

c++ - 使用 boost::spirit::qi::symbols

c++ - 正确使用模板将函数传递给线程池

C++/SDL 渲染文本