虚函数

来源:互联网 发布:卖帽子的淘宝销量 编辑:程序博客网 时间:2024/06/05 18:16

VC6 环境下 Debug 版,Release 版会在此基础上进行优化

关于默认构造

如果一个类中没有虚函数且没有构造,那么编译器则不会给类提供默认构造。只有在有虚函数的情况下,编译器才会提供默认构造,这样才能够完成虚表指针的初始化。

虚函数下的构造和析构

在有虚函数的情况下,编译器会在 构造函数析构函数 中添加 填写虚表 的代码

这里写图片描述

只有在构造和析构函数中才会填写虚表,其他虚函数中不会有对虚表的操作

虚函数的调用

调用虚函数时,会传递虚表指针,且是通过间接调用的。可以通过这个特性来识别虚函数。图中 SetInt函数 和 SetChar函数 都是虚函数,从图中可以推测出 SetInt 为虚表的第一项虚函数,SetChar 为虚表的第二项虚函数。

这里写图片描述

虚函数和其他非虚成员函数的实现流程是一致的,函数内部无差别

关于初始化列表

如果在初始化列表中初始化成员变量,则初始化的汇编代码位置在填写虚表函数的上面;如果是在构造内初始化成员变量,则初始化的汇编代码位置在填写虚表函数的下面。

//构造函数代码,初始化列表初始化变量  CTest()    :m_nInt(1), m_chChar(2)  {    printf("CTest::CTest()\r\n");  }

这里写图片描述

//构造函数代码,构造内初始化变量  CTest()  {    m_nInt = 1;    m_chChar = 2;    printf("CTest::CTest()\r\n");  }

这里写图片描述

虚析构

虚表中的虚析构有一层代理,判断该对象的空间是否需要被释放。因为如果在继承关系下,由于父类子类共用一个对象指针,在虚析构时,先析构子类对象。此时如果对象的空间被释放,就无法调用父类的析构。所以需要在这一层中加判断。

这里写图片描述

其他

虚表中虚函数的排列顺序

虚函数再虚表中的排列顺序是依据虚函数再类中的声明顺序而定。

间接调用和直接调用

通过虚表 间接 寻址访问的情况只有在使用对象 指针引用 来调用虚函数的时候才会出现。当 直接 使用对象调用自身虚函数时,没有必要查表访问。因为已经明确调用的是自身成员函数,根本没有构成多态。

原创粉丝点击