请教一个问题,C++中从虚基类派生出来的类,如果原虚基类中的虚函数在该类中还是虚函数,那么系统会不会给这个派生类创建虚表?或者是只分配一个指针指向第一次出现这些虚函数的基类的虚表?
1楼的朋友谢谢你的回答
我喜欢结交你这样的有研究精神的朋友,你的分析很有研究价值,暂且先不讨论编译器的问题。
我从深入浅出MFC中找到虚表的相关知识,这个肯定不会有错,期待问题能够尽早彻底解决
深入浅出MFC:
1.每一个内涵虚函数的类,编译器都为它做出一个虚拟函数表,表中的每一个元素都指向一个虚函数的地址。
此外,编译器当然也会为类表加上一项成员函数,是一个指向该虚拟函数表的指针(常被称为vptr),每一个由此类别派生出来的类,都有这么一个vptr。
2.虚表以及这种间接呼叫方式。虚表的内容是依据类别中的虚函数声明次序--填入函数指针。派生类别会继承基础类别的虚表(以及所有其他可以继承的成员),当我们在派生类中改写虚函数时,虚表就受了影响;表中的元素所指的函数地址将不再是基类的函数地址,而是派生类的函数地址。
总结:通过深入浅出MFC的内容可以得知:
1,派生类要继承基类的虚表,而不只是说继承基类的虚表指针,所以可以判定,至少从理论上可以判定虚表是要拷贝的,而不是继续用父类虚表,而且多想想也应该可以理解,父类对象指针所指的虚表内容应该和子类不同,因为刚才有提到虚表函数的重定向。可能编译器做了某种优化,再研究
C++虚表问题
对于一个类如果有虚函数,就会在这个类中创建一个虚表,也就会产生一个虚指针指向这个虚表。既然有一个指针指向了虚表,这个类派生后,在派生类中就不必再创建虚表,如果派生类还有自己的虚函数,那么只在派生类中创建该虚函数的一个虚表,产生一个指向该虚表的指针。为每个类设置虚表,初始化虚指针,为...
C++中虚函数的作用和虚函数的工作原理
虚函数在C++中实现多态性,主要作用在于实现动态绑定。基类定义虚函数,子类可以重写该函数。当子类重新定义了父类的虚函数后,当父类的指针指向子类对象的地址时,程序根据对象的实际类型动态调用子类的该函数,而不是父类的函数。这种动态调用发生在运行阶段,称为动态联编。非虚函数的静态联编效率更高,...
C++中是不是每个类(有虚函数)都对应一个virtual function table?_百...
你理解的是对的,子类和父类各有一个虚函数表,并且虚函数指针也是指向各自的。子类先是从父类复制了一个虚函数表,如果子类对父类的虚函数进行了覆盖,则在子类的虚函数表将会用子类的函数地址覆盖父类的,如果没有覆盖,则还是使用父类的函数地址,这样就实现了多态。
关于C++ Virtual 关键字的一切(1):虚函数的内部原理是什么?
在C++中,"关于C++ Virtual关键字的一切(1):虚函数的内部原理"系列文章深入剖析了虚函数的核心机制,特别是动态调度(dynamic dispatch)。文章以连接手机网络的比喻展开,解释了为何需要这种功能,即在抽象层面上,不同的通信协议(如Wifi和蓝牙)需要共享一些通用步骤,如身份认证和连接。虚函数的关键在...
C++中虚继承和一般的继承有什么不同
虚继承,Class A和Class B的关系就会微妙很多。由于C++支持多继承,所以某些情况下会出现下图中的继承关系。这种水晶继承会导致Class D中包含两份Class A的对象。此时就会出现访问歧义的情况。虚继承就可以避免上面的情况。Class A的数据会被放到虚表中。Class D会识别到来自Class B和C的虚表,然后将两者...
多重继承中,每个虚表第一个槽中的type_info是对应basecla
在C++的多重继承中,每个类可以继承自多个基类。然而,内存布局中,基类的顺序在继承时会直接影响虚表的生成。虚表是类的元数据集合,用于存储指向虚函数的指针,是实现多态的关键。每个类的虚表都会被分配在对象的内存布局中,通常位于对象开头的固定位置。虚表的第一个槽用于存放特定类型的信息,而第二...
C++基类子类中,虚函数究竟是怎样判断该调用哪个函数的??
有虚函数时,每个对象的this指针都指向一个虚函数表(Virtual Table)的地址,这个表里存的就是虚函数的地址。编译的时候就决定了,普通函数调用时直接CALL这个函数的地址,而是虚函数时,是从这个虚表里取地址去调用的。
C++中为什么构造函数不能是虚函数,析构函数是虚函数
也即不能完成父类的构造.就会出错.析构函数在某些情况下必须为虚函数(比如你想让你类能够被继承,那么这个类的析构函数最好是虚的,继承一个析构函数不是虚的类是有风险的),值得补充的是,当基类的函数是虚函数,子类的重载的函数也是虚的,即使不加virtual关键字也是虚的。
C++的virtual到底是怎么作用的,它在内部是怎么处理的?
virtual就是告诉编译器这是一个虚函数 编译器就会延迟绑定,在运行时从虚表里找到这个A*指针真正的对象是B类型,从而调用B的fun函数。你可以读一下《深入探索C++对象模型》,此书不读你就不是搞C++的!
c++ 取地址直接就得到地址了 为啥还要强制转换成int* 这不就变成指针类...
b的类型是Base,&b就是Base*型了,第一个cout里面的确可以不用转换成int*,不过为了防止后面的出错和保持一致性,建议习惯这样的写法,理由是假定你需要输出第二虚函数的地址(*((int*)*(int*)&b+1))你需要地址+1,如果不转换成int*,可能会存在+1后偏移值不正确,虚表中都是地址,与Base的...