隐藏在 C++ 中的名称
Name hiding in c++
#include<iostream>
using namespace std;
class ParentClass {
public:
virtual void someFunc(int a){
printf(" ParentClass :: someFunc (int) n");
};
virtual void someFunc(int* a){
printf(" ParentClass :: someFunc (int*) n");
};
};
class ChildClass : public ParentClass {
public:
virtual void someFunc(int* a){
printf(" ChildClass :: someFunc(int*) n");
};
};
int main(){
ChildClass obj;
/* This function call results in an error: */
obj.someFunc(7);
}
第一个给出的错误为
tr2.cpp: In function 'int main()':
tr2.cpp:27:19: error: invalid conversion from 'int' to 'int*' [-fpermissive]
obj.someFunc(7);
^
tr2.cpp:18:18: error: initializing argument 1 of 'virtual void ChildClass::som
eFunc(int*)' [-fpermissive]
virtual void someFunc(int* a){
^
但是如果我们更改方法以接受 char 而不是 int*,那么
#include<iostream>
using namespace std;
class ParentClass {
public:
virtual void someFunc(int a){
printf(" ParentClass :: someFunc (int) n");
};
virtual void someFunc(char a){
printf(" ParentClass :: someFunc (char) n");
};
};
class ChildClass : public ParentClass {
public:
virtual void someFunc(char a){
cout<<a<<endl;
printf(" ChildClass :: someFunc(char) n");
};
};
int main(){
ChildClass obj;
/* This function call results in an error: */
obj.someFunc(7);
}
输出:
ChildClass :: someFunc(char)
带有窗户声音(叮当(。 - ANS:此处的隐式转换。请检查下面的编辑。
因此,名称隐藏在第一个示例中有效,但在第二个示例中不起作用。 谁能解释为什么?我还尝试使用不同数量的参数制作重载的覆盖虚拟函数,例如int func(int a( , int func (int a, int b(,然后仅覆盖其中一个。在这种情况下,名称隐藏也不起作用,派生类能够派生未被重写的基类的虚函数。
为什么这个名称隐藏只在这种特定的一种情况下有效?
编辑 1:
与永恒的上下文 隐式转换的解释。我有另一个程序应该隐藏名称,但没有。在这个版本中,方法根据不同的参数进行区分。
#include<iostream>
using namespace std;
class ABC
{ public:
ABC()
{
cout<<"Constructor ABC"<<endl;
}
virtual void meth1(int a);
virtual void meth2(int a, int b);
};
void ABC :: meth1(int a)
{
cout<<"One"<<endl;
}
void ABC:: meth2(int a, int b)
{
cout<<"Two"<<endl;
}
class BC:public ABC
{
public:
BC()
{
cout<<"Cons B"<<endl;
}
void meth1(int a);
};
void BC :: meth1(int a)
{
cout<<"Three"<<endl;
}
int main()
{
BC b;
b.meth1(5);
b.meth2(6,7);
}
输出:
C:UsersShauryaDesktop>a
Constructor ABC
Cons B
Three
Two
在这种情况下,名称隐藏也不起作用。
当你在ChildClass
中重载someFunc()
时,它会对ParentClass
隐藏两个重载。在第一种情况下,您正在调用一个函数,该函数将int*
作为带有整数的参数,因此它当然会崩溃,因为它无法进行转换。
在第二种情况下,您正在调用一个函数,该函数将char
作为带有整数的参数,因此存在隐式转换,一切都很好。
编辑 1 后更新:
我真的不明白你期望会发生什么:
- 首先你构造一个
BC
,它是来自ABC
的子代,所以有一个调用ABC
的构造函数,然后BC
的 - 之后你调用
meth1()
:由于BC
覆盖了它,所以BC::meth1()
被调用 - 最后你调用
meth2()
:由于BC
不覆盖它,所以ABC::meth2()
被称为
这里发生的唯一"名称隐藏"是BC对meth1的覆盖,但它并没有真正隐藏任何东西......
在您的"编辑 1"中,没有隐藏名称。 b.meth2(6,7)
BC
找不到meth2
,所以ABC
查找。但是,如果您将meth2
重命名为程序中任何地方的meth1
,则由于名称隐藏,它将无法编译:BC::meth1(int)
将隐藏ABC::meth1(int, int)
。
编辑:类成员查找如何工作的简要说明。当编译器看到object.method(args)
,其中object
的静态类型class C
时,它首先在class C
的声明中查找成员函数member
。如果它找到它(或者它是几个重载(,它会停止在其他任何地方查找member
。如果没有,它会按照C++标准部分10.2 Member name lookup
中充分描述的一些神秘规则在C
的基类中查找它。
后,编译器将检查是否可以使用给定参数调用任何候选项。如果是,并且可以毫无异议地完成此操作,则找到该函数。否则,程序格式不正确。此过程称为过载解决,并在标准的第 13.3
部分中进行了描述。
请注意,上面的解释中没有virtual
词。
- 这是我尝试让用户将值输入到数组中.然后将其隐藏为大量的星号
- 结构和双指针隐藏在其他结构中,多层混淆
- 在 cpp 文件中隐藏采用模板参数引用的方法
- 参数包构造函数在类模板中隐藏用户定义的转换
- 如何等待窗口隐藏在Qt中?
- 如何使用类型别名从模板化类中隐藏模板列表
- 在设计 SDK 时,我是否应该在 C++ 头文件中完全隐藏内部类?
- 名称隐藏对静态函数继承的实例使用
- 在 Linux 中使用 ioctl() 获取隐藏功能报告时,零字节消失
- 从多个模板化基类派生时出现"隐藏重载的虚函数"警告
- 如何在 Omnet++ 5.6.1 中隐藏箭头?
- 在C++中隐藏键盘记录器的控制台窗口
- 从静态库使用时隐藏不透明结构的内容
- 隐藏用于聚合初始化的空基类
- 使用智能指针指向 C 库中的结构,该结构通过 typedef 隐藏实现(即不完整的类型)
- Qt中的包装连接方法隐藏了编译器所需的信息
- 隐藏重载虚拟功能的模板化访客:SFINAE 在使用?
- 在 ui 文件中隐藏 QTabWidget 中的单个选项卡窗格?
- C++ [错误] 声明'char '隐藏参数。什么意思?
- 隐藏由 WinAPI 调用创建的窗口