C++虚函数详解

来源:互联网 发布:js省市区三级联动代码 编辑:程序博客网 时间:2024/06/16 12:50

1:在计算机中虚函数表也是占用一定到的内存空间的,且虚函数表由于一旦产生就具有不变性,所以编译器就会经量把它放到稳定(或者说是只读)的内存区。虚函数表vtable在Linux/Unix中存放在可执行文件的只读数据段中(rodata)。在gcc编译器的实现中虚函数表vtable存放在只读数据段.rodata中。

2:实例化类的对象时,对象内存中除了成员变量的大小,还有一个虚函数表指针,而且虚函数表指针放在内存的最前面,虚函数表指针会指向一个虚函数表。

 多态的实现原理如下:当用父类的指针去指向子类对象时,会拿到子类的虚函数表指针,然后找到虚函数表,


通过虚函数表指针的偏移,找到要调用的虚函数的函数指针,从而实现函数的调用。


注意这里的偏移必须是和父类的偏移量是一样的。
 
 

函数的隐藏:没有定义多态的情况下,即没有加virtual的前提下,如果定义了父类和子类,父类和子类出现了同名的

函数,就称子类的函数把同名的父类的函数给隐藏了。

函数的覆盖:是针对多态来说的。如果定义了父类和子类,父类中定义了公共的虚函数,


如果此时子类中没有定义同名的虚函数,那么在子类的虚函数表中将会写上父类的该虚函数的函数入口地址,


如果在子类中定义了同名虚函数的话,那么在子类的虚函数表中将会把原来的父类的虚函数地址覆盖掉,覆盖成子类


的虚函数的函数地址,这种情况就称为函数的覆盖




总结(基类有虚函数的):


  1:每一个类都有虚表

  2:虚表可以继承,如果子类没有重写虚函数,那么子类虚表中仍然会有该函数的地址,只不过这个地址指向的是基


类的虚函数实现,如果基类有3个虚函数,那么基类的虚表中就有三项(虚函数地址),派生类也会虚表,至少有三项,


如果重写了相应的虚函数,那么虚表中的地址就会改变,指向自身的虚函数实现,如果派生类有自己的虚函数,那么


虚表中就会添加该项。


  3:派生类的虚表中虚地址的排列顺序和基类的虚表中虚函数地址排列顺序相同。


      c++的多态性就是通过晚绑定技术来实现的。


  c++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对


象的实际类型来调用相应的函数,如果对象类型是派生类,就调用派生类的函数,如果对象类型是基类,就调用基类


的函数。