虚函数的问题

Kang_TJU 2017-07-27 03:38:33
小弟这两天再看虚函数的原理这一块,遇见了一个关于vtable的问题,求各位大神指导。问题是这样的,基类当中存在一个虚函数,没有其他成员。派生类派生于该基类,重写了这个虚函数。那么,在派生类当中的vtable放置的派生类重写之后的虚函数地址,覆盖了基类当中虚函数的地址。那么,我想问一个问题:基类当中的虚函数去哪了?因为,虚函数的地址只存在vtable当中,但是,派生类由于重写了基类的虚函数,此时vtable里面只有重写后虚函数的地址。基类当中的虚函数地址在派生类当中存在哪呢?比如下面的代码,派生类重写的虚函数当中调用了基类的虚函数,我想问的就是这个基类的虚函数地址它存在派生类的哪里呢?


#include <iostream>

class A {
public:
virtual void print() { std::cout << "A class." << std::endl; }
};


class B : public A {
public:
virtual void print() {
A::print();
std::cout << "B class." << std::endl;
}
};

int main(){


B obj_b;


A* p = &obj_b;

p->print();

return 0;
}
...全文
157 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
xskxzr 2017-07-27
  • 打赏
  • 举报
回复
并不用在对象里存基类的虚函数地址。 编译器知道所有函数的地址,当在编译阶段就能确定调用A::print时,编译器直接找这个函数就好。之所以需要在对象里存虚函数地址是因为在编译阶段遇到print时尚不知道调用A::print还是B::print,仅此而已。
开心秋水 2017-07-27
  • 打赏
  • 举报
回复
虚函数表 只是 对虚函数和多态的一种实现方式,不是所有的编译器都使用虚函数表的,不宜过多纠结于这个问题
verphan 2017-07-27
  • 打赏
  • 举报
回复
http://blog.csdn.net/neiloid/article/details/6934135 这里有两个图,可能会对你有帮助。子类重写虚函数后会在子类的虚函数表覆盖掉原本基类的虚函数指针。
sdghchj 2017-07-27
  • 打赏
  • 举报
回复
成员函数实际上可看作是在编译时插入this指针为第一参数的全局函数。 每个类都对应了一组成员函数,包括虚函数,编译器会将类的所有虚函数地址收集起来形成虚函数表,并在类对象的开头外插入一个指针指向该虚函数表,该虚函数指针不会被复制构造和operator =改变,以保证对象关联的始终是自己所属类的虚函数表,而不是继承链上其它类的虚函数表(所以千万不要对带有虚函数的两个不同类对象使用memcpy之类的bit拷贝进行整体赋值)。 所谓的“覆盖”并不是真的覆盖,这点要理解。基类有自己的虚函数表,派生类有派生类的虚函数表。 用指针调用虚函数时,会去找指针指向的对象里的虚函数表指针,通过该虚函数表指针找到虚函数表,再通过虚函数的地址偏移量就能找到对应的虚函数地址。所以通过指针调用虚函数就得看看指针指向的是什么类型的对象,才能表现出相应类的行为,实现金态。 如果在派生类虚函数中再显示调用基类对应成员函数时,是通过基类名去调用函数,是可以直接根据函数地址调用到函数的,不需要通过虚函数表指针加虚函数地址偏移量的方式。 引用与指针类似。 当派生类对象赋值通过复制构造或者operator=给基类对象初始化或赋值时,不会改变基类对象的虚函数表指针,因此也常说的通过对象去调用虚函数,不能到达多态的目的。
「已注销」 2017-07-27
  • 打赏
  • 举报
回复
虚函数表中包含的是当前类会调用的那个函数的指针。 class B中重写了print函数,那么在class B的虚函数表中只会包含B::print()的指针,不会包含A::print()的指针。
冬南风 2017-07-27
  • 打赏
  • 举报
回复
虚函数的地址只存在vtable当中。 这句话表述不太对。 是把虚函数的地址填到vtable,先有虚函数的地址然后才填入vtable

64,691

社区成员

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

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