被子类虚函数覆盖后,如何直接子类调用父类虚函数的虚函数

我发现在子类函数中调用父类的方法, 即使没有发生名字覆盖或者虚函数改写, 感觉有点奇怪啊.. 还有继承自父类的属性, 也是这样...

假设 void printf() 这个函数基类子类中都有。现在我把基类中变为虚函数:

这是为什么?哪里有写着要调用子类函数了?为什么不是调用基类函数?

可选中1个或多个下面的关键词,搜索相关资料。也可直接点“搜索资料”搜索整个问题。

有虚函数时,每个对象的this指针都指向一个虚函数表(Virtual Table)的地址,这个表里存的就是虚函数的地址。编译的时候就决定了,普通函数调用时直接CALL这个函数的地址,而是虚函数时,是从这个虚表里取地址去调用的。

每个对象的this指针都指向一个虚函数表。。。。。。。每个对象?你是说基类子类的this指针都指向虚函数表?????
我设定的是基类函数为虚函数,按此说法,这是从虚表里调用的,那也应该调用的是基类的虚函数啊?
 父类的这个函数是虚函数,子类里自然也是了,子类里这个关键字是可省略的
补充一下:
如果觉得我的回答难理解,可以就记住一个概念:普通函数是属于类的,虚函数是属于对象的。
也就是说,普通函数,指针类型是哪个类的,调用的函数就那个类的。
虚函数,不管指针类型是那个类的,你new的是谁,决定你最终调用的是谁的函数。
我就是想知道具体调用的流程是怎样的,你之前说从虚表里调用,这没问题。
那么基类里也有虚函数啊,他为什么调用子类的?
你说子类也自动变成虚函数。这也没问题,但同样是虚函数,为什么不调用基类却调用子类的?
还有,我就是想刨根问底,尽管来哈哈哈,越详细我越爽
 因为规则就是这样设定的,编译器就得按这个规则来编译,这个没啥可说的。
编译的时候代码就生成成这样了。普通函数直接CALL这个函数的地址,要虚函数的话,得先取虚表地址 mov eax,[this] , 再取虚函数地址调用 call dword ptr [eax] 。就放了两句关键汇编,而且默认为虚函数地址正好在虚表中是第一个的时候就这样
想知道的更详细只有你自己去看汇编的,我已经没法表达了

原因:由于子类重载了基类的虚函数,所以在子类对象的虚函数表里面的函数地址是子类的,而不是父类的,所以p->printf(),肯定调用的是子类的printf函数了。

定义了虚函数之后,在执行的时候,系统会自动的匹配与之相对应的合适的成员函数。

这里的话p是指向son的指针,那么他会先调用son里面的成员函数。

p是指向son的指针,那么他会先调用son里面的成员函数。如果我没有设立虚函数呢?p是指向son的指针呀,它怎么不调用son函数?

如果子类实现了的就掉子类,子类没实现的就调父类的。

我要回帖

更多关于 子类调用父类虚函数 的文章

 

随机推荐