类中具有相同变量名的多重继承 [英] Multiple inheritance with the same variable name in the classes

查看:71
本文介绍了类中具有相同变量名的多重继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不小心遇到了在多重继承中使用的类中具有相同名称的成员变量的问题.我的基本想法是成员变量是简单的合并",即发生了多个声明.编译器甚至没有告诉我警告,请参阅下面的MWE. 我知道让变量具有相同的名称是一个坏主意,因此我认为以我的方式引用它们至少是模棱两可的.所以我期望至少会有警告或错误.

1)为什么编译器没有至少写出警告?

2)如何在内部解决这些变量的处理? (我想使用了别名,例如HW :: I和Other :: I,但是它们与SW1 :: I和SW2 :: I的关系如何?)

#include <iostream>
struct Other { int I;};
struct HW { int I;};
struct SW1 : Other, HW { int I;};
struct SW2 : HW, Other { int I;};
struct D : SW1 { };
struct E : SW2 { };

int main()
{
    E* e = new E;
    D* d = new D;
    e->I = 3;
    SW1* pc1 = dynamic_cast<SW1*>(d);
    pc1->I = 2;
    std::cerr << d->I;
    std::cerr << e->I;
    SW2* pc2 = dynamic_cast<SW2*>(e);
    pc2->I = 1;
    std::cerr << d->I;
    std::cerr << e->I;
}

解决方案

编译器正确无误,无法诊断您的代码有任何问题.正如您所构造的那样,该代码并不是模棱两可的.从本质上讲,如果一个名称与多个变量(或您的情况下的类成员)具有相同的匹配性,则该名称是模棱两可的.

在评估e->I时,找到的第一个候选对象是I,它是类SW2的成员(通过继承). SW2从其基类继承的I成员不如Sw2直接定义的成员那样好.

类似地,pc1->I明确地是SW1的成员,d->I相同,并且pc2->I明确地是基类SW2的成员.

如果SW2没有自己的名为I的成员(即struct SW2: HW, Other {};(.),则在评估e->I时会出现歧义.在这种情况下,当评估e->I时,名称解析会出现在SW2中对于名称为I的成员,但找不到它.然后解析名称将考虑两个基类,分别为HWOther,它们都有一个名为I的成员.表达式e->I是模棱两可的-编译器将发出诊断信息,即错误(不仅仅是警告),在这种情况下,程序员可以使用范围(::)运算符来明确解决歧义.例如,e->HW::Ie->Other::I完全限定了名称.

您是正确的,在类层次结构中如此多次使用名称是一个坏主意.既因为很难以对编译器有意义的方式正确解决歧义,又因为仅仅凡人通常很难遵循逻辑.

I accidentally run into the problem having member variables with the same name in classes used in multiple inheritance. My basic idea was that the member variables are simple "merged", i.e. a multiple declaration happens. The compiler did not tell me even a warning, see the MWE below. I understand that it is a bad idea to have variables with the same name, so I think it is at least ambiguous to refer to them in the way I do; so I expected at least a warning or maybe an error.

1) Why the compiler does not write out at least a warning?

2) How handling of those variables is solved internally? (I guess aliases like HW::I and Other::I are used, but how they relate to SW1::I and SW2::I?)

#include <iostream>
struct Other { int I;};
struct HW { int I;};
struct SW1 : Other, HW { int I;};
struct SW2 : HW, Other { int I;};
struct D : SW1 { };
struct E : SW2 { };

int main()
{
    E* e = new E;
    D* d = new D;
    e->I = 3;
    SW1* pc1 = dynamic_cast<SW1*>(d);
    pc1->I = 2;
    std::cerr << d->I;
    std::cerr << e->I;
    SW2* pc2 = dynamic_cast<SW2*>(e);
    pc2->I = 1;
    std::cerr << d->I;
    std::cerr << e->I;
}

解决方案

The compiler is correct not to diagnose any problems with your code. The code, as you've constructed it is not ambiguous. Essentially, a name is ambiguous if it is an equally good match for more than one variable (or class member in your case).

When evaluating e->I, the first candidate found is the I that is a member (via inheritance) of class SW2. The members of I that SW2 inherits from its base classes are not as good a match as the member defined directly by Sw2.

Similarly, pc1->I is unambiguously the member of SW1, d->I is the same, and pc2->I is unambiguously the member of the base class SW2.

Ambiguity would occur in evaluating e->I if SW2 did not have its own member named I (i.e. struct SW2: HW, Other {};( . In that case, when evaluating e->I, the name resolution looks in SW2 for a member named I, and doesn't find it. Resolving the name then considers the two base classes, HW and Other, which both have a member named I. They are equally good matches, so the expression e->I is ambiguous - and the compiler will issue a diagnostic i.e. an error (not just a warning). In that case, it is possible for the programmer to explicitly resolve the ambiguity using the scope (::) operator. For example, e->HW::I or e->Other::I which fully qualifies the name.

You are right that such multiple usage of a name within a class hierarchy is a bad idea. Both because it can be difficult to correctly resolve the ambiguity in a way that makes sense to a compiler, and because mere mortals will often have trouble following the logic.

这篇关于类中具有相同变量名的多重继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆