C++ 子类覆盖了父类的虚函数后,为什么还可以引用父类的函数?

zbx1231 2015-12-08 11:29:40
以前一直没有仔细考虑这个问题,今天突然想到,一时半会想不通,网上也没找到答案,只好来求教
例如
class A
{
public:
virtual void func(){ cout<<"A"<<endl; }
}
class B : publc A
{
public:
virtual void func(){ cout<<"B"<<endl; }
}

B b;
b.A::func();

输出为 A

那么问题来了,B继承了A之后并且重写了 A 的方法 ,A 的func函数被覆盖了 ,那编译器是怎么找到A 的函数并输出A 的?B的虚函数表中,func()不是被替换了吗?
...全文
2289 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_40956846 2017-12-08
  • 打赏
  • 举报
回复
注意作用域运算符
bbqbbm 2017-03-16
  • 打赏
  • 举报
回复
搜java的多态发生时,如何调用父类中被重写的方法时,看到你这个;我这么理解的,只是用来记住规则,不一定对。在c++中,继承关系使子类拥有了父类的完整拷贝,哪怕是私有的,哪怕是虚函数,同时维护了一个虚表,所以这个::限定符,允许了在子类对象中找到父类的的任何方法,如果没有这个限定符,又发生了多态,那么就是运行时多态,则从虚表找函数地址。然而在java中,继承只是从父类拷贝能继承下来的非private的,只有能继承下来的,并且重写的才真正完成了多态需要的重写。 另外不同的一点时c++父类构造函数内调用虚函数不发生多态,java中父类构造函数里调用重写函数能发生多态。
paschen 版主 2015-12-08
  • 打赏
  • 举报
回复
另外这不叫覆盖,应该叫重写
paschen 版主 2015-12-08
  • 打赏
  • 举报
回复
但如果还是想用A的,可以用这种方法写,编译时将不会先查虚表再调用,而是直接调用A的
fefe82 2015-12-08
  • 打赏
  • 举报
回复
b.A::func(); 这中格式的意思是:不要去虚表找了,我就要调用 A 的。
lm_whales 2015-12-08
  • 打赏
  • 举报
回复
另外虚函数重载, 只是通过指针和引用调用函数, 可以实现多态(统一调用形式,根据指针,引用类型的不同,调用不同类实现的函数) 其他和重载函数,没有太多不同 也一样会隐藏父类的同名函数的。 C++虚函数有继承性, 基类的虚函数 派生类 同名,同参,同签名( 指的是 const 与否)的函数, 不论有没用 virtual 定义,都是虚函数。
lm_whales 2015-12-08
  • 打赏
  • 举报
回复
C++比C多了个作用域限定符:: 所以,隐藏的不是很深,还是可以揪出来用的 全局函数,变量,类型,enum 常量 被隐藏,可以用 ::引用 名空间内 函数,变量,类型,enum 常量被隐藏,可以用 名空间名:: 引用 类作用域的函数,变量,类型,enum 常量 被隐藏,可以用 类名:: 引用 只有函数 和 函数内部的语句组作用域,名字被隐藏,无法引用
bravery36 2015-12-08
  • 打赏
  • 举报
回复
不是任何时候都会去查虚表的,可以知道调哪个的时候就直接写地址了.
Saleayas 2015-12-08
  • 打赏
  • 举报
回复
虚函数是指这个函数的签名。 而 这个虚函数在类中的实现不是,她是一个实实在在的成员函数。 和普通的函数一样的。 如果这个函数是虚函数,此时编译器会把其地址放在虚表中。 所以这个函数有两个入口。 第一个就是你这样呼叫,和普通的成员函数一致。 第二个是通过引用呼叫,此时编译器会通过虚表来呼叫。 此时需要添加一个修正 this 指针的转换函数。

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧