1
381
从你问题的措辞来看(你用了“隐藏”这个词),你已经知道这里发生了什么。这种现象被称为“名称隐藏”。出于某种原因,每次有人问关于 为什么? 名字隐藏发生了,人们要么说这个叫做“名字隐藏”,解释它是如何工作的(你可能已经知道了),要么解释如何覆盖它(你从来没有问过),但似乎没有人关心解决实际的“为什么”问题。 决定,名称隐藏背后的基本原理,即 为什么? 它实际上被设计成C++,是为了避免某些反直觉的、不可预见的和潜在的危险行为,如果继承的重载函数集被允许与给定类中的当前重载相混合,则可能发生这种行为。您可能知道,在C++中,超载解析是通过从候选集中选择最佳函数来工作的。这是通过将参数类型与参数类型匹配来实现的。匹配规则有时可能很复杂,并且常常导致结果被没有准备的用户认为是不合逻辑的。向以前存在的一组函数中添加新函数可能会导致过载分辨率结果发生相当大的变化。
例如,假设基类
中给出了另一个示例 C++的设计与实现 ,第77页:
如果没有这个规则,B的状态将部分更新,从而导致切片。 这种行为在语言设计时被认为是不可取的。作为一种更好的方法,它决定遵循“名称隐藏”规范,这意味着每个类都从一个“干净的工作表”开始,与它声明的每个方法名相关。为了重写此行为,需要用户执行显式操作:最初是对继承方法的重新声明(当前已弃用),现在是显式使用using声明。 正如您在最初的文章中正确地观察到的(我指的是“非多态性”的评论),这种行为可能被视为违反IS——类与类之间的关系。这是真的,但很明显,在当时,人们决定,以最终的名义,隐藏将被证明是一种较小的邪恶。 |
2
43
名称解析规则表示名称查找将停止在找到匹配名称的第一个作用域中。此时,过载解决规则开始寻找可用功能的最佳匹配。
在这种情况下,
解决方案是通过派生类中的using声明引入基声明:
…将允许名称查找规则查找所有候选项,因此重载解决方案将按预期进行。 |
3
13
这是“按设计”。在C++中,这种类型的方法的超载分辨率如下所示。
由于派生函数没有名为“gogo”的匹配函数,因此重载解析失败。 |
4
2
名称隐藏是有意义的,因为它可以防止名称解析中的歧义。 考虑此代码:
如果
参考文献: http://bastian.rieck.ru/blog/posts/2016/name_hiding_cxx/ |
rookie · 检查函数模板的所有参数包参数是否属于int 1 年前 |
ivaigult · -W转换和隐式字符串到布尔类型转换 1 年前 |
rainer · 后台插入程序的初始化 1 年前 |
Community wiki · 以理智、安全和高效的方式复制文件 1 年前 |
Shefali Kanaujia · 对C中向量的向量进行排序++ 1 年前 |
Ma Joonyoung · 粗粒度和细粒度链表的时间比较 1 年前 |