本文共 1524 字,大约阅读时间需要 5 分钟。
知识点1:虚函数(virtual 函数名();)——解决“如果你以一个基类指针指向一个派生类对象,那么通过该指针,你只能访问基础类定义的成员函数”此问题。
原因:如果你以一个基类指针指向一个派生类对象,那么通过该指针,你只能访问基础类定义的成员函数;如果以派生类指针指向基类对象,这种做法相当危险,一般不会这么定义
知识点2:同名成员函数——如果基类和派生类定义了相同的成员函数,那么对象指针调用成员函数时,到底调用的是哪个成员函数,最终取决于这个指针的原型,而不是指向的对象类型,不过虚函数可以解决此问题,可以在“一个基类指针指向一个派生类对象”的情况下,调用派生类对象的同名成员函数
知识点3:虚析构函数(virtual ~类名();)——解决在动态多态中,内存泄漏的问题
知识点4:virtual限制用法——不能修饰类外申明并定义的函数(全局函数),即只能修饰类内申明并定义的函数(通常在申明时修饰即可);virtual不能修饰类内的静态成员函数;virtual不能修饰内联函数;virtual不能修饰构造函数。
知识点5:继承虚函数——注意上述,虚函数和虚析构函数,一定要在基类里给函数或者析构函数添加virtual关键字。若基类里,申明虚函数,则派生类里会默认继承虚函数,当然最好也给其他类加上virtual关键字
注:在C++11新标准中,可以使用override关键字来说明派生类中的虚函数。
知识点6:析构函数最好都添加virtual关键字,使之成为虚析构函数,这样避免之后出现的内存泄漏问题(即内存占用不释放),因为并不知道未来继承的子类会不会在其构造函数中申请内存
知识点7:虚函数原理
指针指向对象——对象指针;指针指向函数——函数指针
申明基类的虚函数时,会自动生成虚函数表,用于寻找虚函数的入口地址,如果派生类继承基类的虚函数,且没有自定义同名虚函数时,则也会自动生成虚函数表,而自动生成的虚函数表指针,会指向基类虚函数的相同入口地址;但如果派生类继承基类,并自定义同名虚函数时,则会自动生成虚函数,但指向与上述不同的虚函数入口地址(函数的覆盖)。
知识点8:函数的覆盖和隐藏
当基类和子类出现同名函数时,此时出现函数的隐藏;但若定义了虚同名函数,则此时出现函数的覆盖。(可参考知识点7,即虚函数表的地址异同问题)
知识点9:虚析构函数原理
理论前提:执行完派生类的析构函数就会执行基类的析构函数
当在基类中,申明虚析构函数后,则在派生类中,也会在默认生成虚析构函数,即在派生类的析构函数前,默认加上virtual关键字
这样可以解决内存泄漏问题,即解决了“释放了指向基类对象的指针所占内存,但忘了释放派生类里分配给另一指针的内存(假如另一指针存在的话)”,因为派生类的虚函数指针表的作用(请参考知识点7),结果就是先执行派生类的析构函数,再执行基类的析构函数,从而无内存占用,解决内存泄漏问题。
知识点10:对象大小(sizeof(对象名))
这表明对象中的数据成员占用的内存大小,并不包含成员函数;若对象中,无数据成员,则默认分配其一个字节内存大小(若包含虚函数或虚析构函数,则生成虚函数表,此时占用4个字节的内存,即虚函数表指针的大小)。
注:一个指针所占用4个字节的内存
知识点11:虚函数表
a.当类中定义了虚函数或者虚析构函数时,则在类实例化对象时,自动生成虚函数表,并在对象中生成一个虚函数表指针
b.在多态的情况下,虚函数表指针在对象中所占据的内存位置是对象前4个寄存内存单元,后面排列的是其它数据成员
c.每个类只有一份虚函数表,所有该类的对象共用同一张虚函数表
转载地址:http://fjzsz.baihongyu.com/