C++虚函数学习笔记(仅供参考)

1、虚函数的作用:
允许在派生类中重新定义与基类同名的函数,并且可以通过基类的指针或引用来访问基类和派生类中的同名函数。

2、虚函数的工作原理
编译器处理虚函数的方法:对每个对象添加一个隐藏成员。
隐藏成员中保存了一个指向函数地址数组的指针,这种数组称为虚函数表(vtbl)。虚函数表中存储了为类对象进行声明的虚函数的地址。
例如:基类对象包含一个指针,该指针指向基类中所有虚函数的地址表。派生类对象将包含一个指向独立地址表的指针如果派生类提供了虚函数的新定义

,该虚函数表将保存新函数的地址,如果没有重新定义虚函数该vtbl将保存函数原始版本的地址,如果派生类定义了新的虚函数,则该函数的地址也将被

添加到vtbl中。
注:无论类中包含了多少虚函数,都只需在对象中添加一个地址成员,只是表的大小不同。

C++规定:当一个成员函数声明为基类后,其派生类中的同名函数也自动成为虚函数。

虚函数使用的注意事项:
一、只能用virtual声明类的成员函数,使它成为虚函数,而不能将类外的普通函数声明为虚函数,因为虚函数的作用是允许在派生类中对基类的虚函数

重新定义。显然,它只能用于类的继承层次结构中。
二、一个成员函数被声明为虚函数后,在同一类族中的类就不能再定义一个非virtual的但与该虚函数具有相同参数的(包括个数和类型)和函数返回值

类型的同名函数。


静态关联与动态关联:
关联:确定调用具体对象的过程称为关联。
静态关联:函数重载和通过对象名调用的虚函数,在编译时可确定其调用的虚函数属于哪一个类,其过程称为静态关联;
动态关联:在运行阶段将类和对象绑定在一起的过程称为动态关联;如:在虚函数中的pt->display(),无法确定确定应调用哪一类的虚函数,在这样的情

况下,编译系统把它放到运行阶段处理,在运行阶段确定其关联关系。在运行阶段,基类指针变量先指向某一个类的对象,然后通过此指针变量调用该对

象中的函数,此时调用哪一个对象的函数就确定了。

注:编译只做静态的语法检查,故自从语句的形式是无法确定调用对象的。


什么为虚函数时的依据:
一、首先看成员函数是否会作为基类。然后看成员函数在类的继承后有无可能被更改功能,如果希望更改其功能的,一般应该将它声明为虚函数。
二、如果成员函数在类被继承后功能不许修改,或派生类用不到该函数,则不要将它声明为虚函数。不要仅考虑到作为基类而把类中的所有成员函数都声

明为虚函数。
三、应考虑对成员函数的调用是通过对象名还是通过基类指针或引用去访问,如果是通过基类指针或引用去访问的,则应当声明为虚函数。
四、有时,再定义虚函数时,并不定义其函数体,即函数体是空的。它的作用只是定义了一个虚函数名,具体功能留给派生类去添加。


注意:使用虚函数时,系统要有一定的空间开销。当一个类带有虚函数时,编译器会为该类构造一个虚函数表,它是一个指针数组,存放每个虚函数的入

口地址。系统进行动态关联时的时间开销是很少的,因此多态性是高效的。

虚析构函数:
普通析构函数:系统只会执行基类的析构函数,而不执行派生类的析构函数;
虚析构函数:将析构函数声明为虚函数,由该基类派生出的所有的派生类的虚构函数也自动成为虚函数,使之执行所有派生类的析构函数(即使派生类的

析构函数与基类的析构函数名字不相同)。
注:在程序中,最好把基类的析构函数声明为虚函数。
程序员一般都习惯声明虚析构函数,即使基类不需要析构函数,也显示的定义一个函数体为空的虚析构函数,以保证撤销动态存储空间时能得到正确的处

理。


注:构造函数不能声明为虚函数,因为在执行构造函数时类对象还未完成建立过程,当然谈不上函数与类的关联。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值