基类的继承与指针

时间:2013-09-17 12:14:31

标签: c++ inheritance ambiguity

我正在经历这个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();
}

3 个答案:

答案 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)的不同之处在于。