我正在经历这个Book而我无法绕过这个:
如果B::f(int)
隐藏A::f()
,为什么pa1->f();
不会出错?
名称隐藏是否意味着f()
中不存在函数class B
?如果pa1
指向class B
的对象,则pa1->f();
会导致错误,就像b.f()
一样!
请解释一下,因为我无法通过这本书理解它! 提前谢谢!
#include <iostream>
using namespace std;
struct A {
virtual void f() { cout << "Class A" << endl; }
};
struct B: A {
void f(int) { cout << "Class B" << endl; }
};
struct C: B {
void f() { cout << "Class C" << endl; }
};
int main() {
B b; C c;
A* pa1 = &b;
A* pa2 = &c;
// b.f();
pa1->f();
pa2->f();
}
答案 0 :(得分:2)
如果您尝试从f()
的范围调用B
,则会出错。但是,您通过指向基类的指针调用它。在这种情况下,名称查找和重载解析基于对象的静态类型A*
完成。从那里,f()
可见。
答案 1 :(得分:1)
如果
B::f(int)
隐藏A::f()
,为什么pa1->f();
不会出错?
因为pa1
指向A
,而A
有一个名为f
的成员,可以像这样调用。在这种情况下,任何其他类(包括B
)都无关紧要。
名称隐藏是否意味着,
f()
类中不存在函数B
?
没有。这意味着,在B
的上下文中,可以通过非限定查找找到的唯一名为f
的函数是B::f
。它不会从任何其他上下文中删除f
,也不会阻止限定查找(例如b.A::f()
)找到它。
如果
pa1
指向类B
的对象,则pa1->f();
会导致错误,就像b.f()
一样!
动态类型为B
,因此这是使用(在运行时)调用虚拟函数的类型。编译器根据静态类型选择非虚函数,即A
。通常,编译器不知道动态类型;它只知道指针指向A
或某个未知的派生类。
答案 2 :(得分:1)
呼叫pa1-&gt; f();首先路由到类型A的对象,因为pa1是指向该类型的指针。如果有一个与调用的确切(!!)签名匹配的函数,则virtual关键字会将调用重新路由到类型B.由于B类中没有这样的功能,因此执行A类功能。
我的意思是,在这种情况下,函数不会相互“隐藏”,因为签名不同。 [f(void)vs. f(int)]
编辑: 更清楚。 f(int)和f(void)是两个完全不同的函数。与f(void)到g(int)的不同之处在于。