C++中的隐藏规则是什么?

3

我对名称隐藏和信息隐藏这两个术语感到困惑。更重要的是,在C++中,有什么隐藏规则?有人能给我一个定义吗?


你从哪里听到这些术语的? - GManNickG
没有正式命名为“隐藏规则”的东西。有许多规则涉及隐藏,通常是多个共享相同标识符(文本名称)的项目。您能更具体地说明您所说的是什么吗? - Ben Voigt
3个回答

6

Name hiding 发生在你覆盖一个类时:

struct A
{
    int x;
    int y;

    void foo();
    void bar();
};

struct B : A
{
    int y;
    void bar();
};

在类B中,名称xfoo是明确的,并且引用基类中的这些名称。然而,名称ybar隐藏基本名称。考虑以下示例:
B b;
b.bar();

函数名指的是函数B::bar的名称,由于基类名称被隐藏,因此没有歧义。如果您想要基础函数,必须明确地说明:b.A::bar()。或者,您可以在类定义中添加using A::bar;以“取消隐藏”名称,但这样会导致名称的不确定性(如果存在不同的重载,则这是有意义的)。也许最常令人困惑的名称隐藏示例之一是operator=,它存在于每个类中并且“隐藏”任何基类运算符;因此,对于未提供显式赋值运算符的每个类都会产生隐式定义的操作符,如果您已经在基类中定义了赋值运算符,这可能会令人惊讶。

2
更普遍地说,名称隐藏发生在内部作用域和外部作用域存在相同名称的情况下。int a = 1; { int a = 2; } assert(a == 1); 派生类和基类是内部作用域和外部作用域的一个例子。 - Oktalist
@Oktalist:谢谢,这是一个非常好的观点。但是需要注意的是,访问这些任意隐藏名称的范围是有限制的;::a只能帮你到这个程度。 - Kerrek SB

3

2
“隐藏规则”是指如果你派生一个类并且添加了一个与父类成员同名的成员,那么这个成员就会“隐藏”父类版本:
struct Base {
    void foo();
};

struct Derived : Base {
    void foo(int);
};

如果你在派生类实例方法中尝试使用foo(),即使确实存在于Base中,也会出现错误。

给出的原因是为了避免混淆,例如基类可能有一个void foo(double),而派生类有void foo(int)。这样做的理由是比起在结果程序中产生意外行为,更好的选择是停止编译。

在派生类中,您可以使用using显式地“导入”基类名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接