1

我正在阅读这本书,但我无法理解这一点:

如果B::f(int)隐藏A::f(),为什么不pa1->f();给出错误?

名称隐藏不是意味着该功能f()不存在class B吗?如果pa1指向class Bthen的对象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();
}
4

3 回答 3

2

如果您尝试f()B. 但是,您通过指向基类的指针来调用它。A*在这种情况下,名称查找和重载解析是基于对象的静态类型完成的。从那里,f()是可见的。

于 2013-09-17T12:21:56.110 回答
1

如果B::f(int)隐藏A::f(),为什么不pa1->f();给出错误?

因为pa1指向A, 并且A有一个被调用的成员f,可以这样调用。在这种情况下,任何其他类(包括B)都是不相关的。

名称隐藏不是意味着该函数f()在类中不存在B吗?

不,这意味着,在 的上下文中,唯一可以通过非限定查找找到的B调用函数是。它不会从任何其他上下文中删除,也不会阻止它被合格的查找找到,例如.fB::ffb.A::f()

如果pa1指向类的对象,B那么pa1->f();应该会导致错误b.f()

动态类型是,所以这B是(在运行时)用来调用函数的类型。编译器根据静态类型选择非虚函数,即A. 一般来说,编译器不知道动态类型;它所知道的只是指针指向一个A或某个未知的派生类。

于 2013-09-17T12:57:08.780 回答
1

调用 pa1->f(); 首先路由到类型 A 的对象,因为 pa1 是指向该类型的指针。如果存在与调用的精确(!!)签名匹配的函数,则 virtual 关键字会将调用重新路由到类型 B。由于类型 B 中没有这样的函数,所以执行类型 A 的函数。

我的意思是,在这种情况下,函数不会因为签名不同而相互“隐藏”。[f(void) 与 f(int)]

编辑:要更清楚。f(int) 和 f(void) 是两个完全不同的函数。与 f(void) 到 g(int) 一样不同。

于 2013-09-17T13:39:59.637 回答