假设,我想创建一个如下所示的类并且不使用虚拟继承。 从“下层”实例访问“上层”类成员的语法是什么? 已经为左和右计算了一些方法,但不确定哪个是“规范”正确的。以及如何访问成员下---上层的方式?
/* 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
作为命名空间包含来自 left
和 right
的两个 upper
和一个来自它自己的声明。虽然您可以为 left
和 right
内的 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/