虚函数的工作原理和注意事项

一、编译器如何处理虚函数

  • 编译器为每一个对象添加一个隐藏成员,隐藏成员中保存了一个指向函数地址数组的指针。这个数组被称为虚函数表

  • 虚函数表中存储了为类对象进行声明的虚函数的地址。

  • 如果派生类提供了虚函数的新定义,改新函数将保存新函数的地址,如果派生类没有重新定义虚函数,那么虚函数表保存函数原始版本的地址

  • 不管类中包含的虚函数的个数有多少,都只给对象提供一个地址成员(隐藏成员),只是虚函数表的大小不同

  • 虚函数属性会被继承,也就是说一个基类有虚函数表,那么派生类也会有一个虚函数表

  • 如果一个虚函数只被声明,并没有定义(实现),那么在编译时,会报错

二、使用虚函数的成本

  • 1、每个对象都将增大,增大量为存储地址的空间
  • 2、对于每个类,编译器都将创建一个虚函数的地址表
  • 3、对于每个函数调用,都需要执行查表操作

三、有关虚函数的注意事项

  • 1、在基类中使用virtual声明的方法,在基类和所有的派生类中都是虚的
  • 2、如果使用指向对象的引用或者指针调用虚方法,程序将使用对象类型定义的方法,而不使用为引用或者指针类型定义的方法。
  • 3、如果定义了虚函数的类被当做基类,那么应将那些要在派生类中重新定义的类方法声明为虚的
  • 4、构造函数不能是虚的---因为不符合继承的机制
  • 5、析构函数应当是虚函数,除非类不做基类
  • 6、友元函数不是类成员,因此也不能是虚函数,因为虚函数是要被子类重新定义的。
  • 7、在派生类中重新定义的函数必须和基类的函数原型一致,包括参数,(不是函数重载),但当返回值是基类的指针或引用,则允许修改返回值为指向派生类的指针或引用。这种特性被称为返回类型协变。
  • 8、如果基类声明被重载了,则应该在派生类中重新定义所有的积累版本。也就是说所有被重载的函数版本都需要被重新定义
四、c++如何实现虚函数

如果一个类有一个或多个成员函数都是虚函数,那么编译器会为该类创建一个表,改表被称为虚函数表,对于每一个虚函数成员,虚函数表都有一个对应的指针,指向虚函数。(即虚函数表保存每一个虚函数的内存地址),每个指针指向其对应的虚函数的代码所在的位置。

如果一个虚函数是继承基类并且未做任何更改,那么它的虚函数表的表入口指向父类中该函数的定义,同理,如果改继承的虚函数有了新的定义(实际是实现),那么虚函数表中新定义的虚函数的指针指向新定义函数的代码入口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值