(一)
1、C++ Virtual Table (虚函数表) 是C++ 实现多态的方式。
2、每一个具有虚函数(使用virtual关键字定义的函数)的类的具体实现,都有一个指向虚函数的指针表。
3、指向虚函数表的指针是作为数据成员存在于所有对象中。当调用虚函数时,查找对象的虚函数表指向正确的派生类函数。虚函数表是由虚函数指针组成的数组。
4、静态绑定 & 动态绑定。
对于类的普通成员函数使用的是静态绑定,发生在编译期。
对于类的虚函数发生在运行期是动态绑定,发生在运行期。
虽然虚函数的调用是在运行期才确定,但是虚函数表的创建是在编译阶段就完成构建。
(二)
虚函数按照其声明顺序放于表中。
父类的虚函数在子类的虚函数前面。
(三)
虚表中派生类覆盖的虚函数的地址被放在了基类相应的函数原来的位置 (SubClass的a()函数替换了Base的a())
派生类没有覆盖的虚函数延用父类的。
(四)
原则
单继承
虚函数表派生类覆盖的虚函数的地址被放在了基类虚函数表对应的函数原来的位置。(覆盖)
派生类没有覆盖的虚函数就延用基类的。同时,虚函数按照其声明顺序放于表中,父类的虚函数在子类的虚函数前面。
多继承
1. 每个基类都有自己的虚函数表
2. 派生类的虚函数地址存依照声明顺序放在第一个基类的虚表最后.
(五)
(六)
构造和析构函数是否能为虚函数?
构造函数不能为虚函数,因为如果对象都没有创建,就无法调用虚函数,构造函数为虚函数是没有任何意义的。
析构函数可以是虚函数,在某些情况下必须为虚函数:当一个基类指针指向动态分配的子类对象时,这时如果 delete该基类指针,如果基类的析构函数不是虚函数,那么只会释放基类自己的那部分,而派生类自己的那
部分得不到释放,这是不安全的,如果子类的数据成员部分有动态分配的资源,那么就发生了内存泄漏,但是
可以将基类的析构函数定义为虚析构函数,这样做即使是delete一个指向派生类对象的基类指针,也会先调用派生类的析构函数,在调用父类的析构函数。所以将析构函数设为虚函数总是正确的,后面会做实验验证
如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!
加入交流群
请使用微信扫一扫!