前言
虚函数执行速度要稍慢一些。为了实现多态性,每一个派生类中均要保存相应虚函数的入口地址表,函数的调用机制也是间接实现。所以多态性总是要付出一定代价,但通用性是一个更高的目标。
实验环境
Windows10 企业版
Visual Studio2017 15.8.1
引入虚函数后内存大小变化
没有虚函数时类占用内存大小
#include<iostream> using namespace std; class Base { public: Base() { cout << "Create Base" << endl; } ~Base() { cout << "Free Base" << endl; } public: void Show() { cout << "This is Base Show()" << endl; } private: int x; }; void main() { cout << sizeof(Base) << endl; Base b; }
占用内存为4字节。在x86 模式下,整形变量大小为4字节
有虚函数时类占用内存大小
#include<iostream> using namespace std; class Base { public: Base() { cout << "Create Base" << endl; } ~Base() { cout << "Free Base" << endl; } public: virtual void Show() { cout << "This is Base Show()" << endl; } private: int x; }; void main() { cout << sizeof(Base) << endl; Base b; }
占用内存为8字节。在x86 模式下,整形变量大小为4字节。剩下4字节是虚函数表指针,指针变量在x86下占内存大小4字节。
代码中只定义了一个虚函数,定义多个虚函数,类的大小还是8。虚函数表的指针指向的是虚函数表的入口地址
虚函数表
1 #include<iostream> 2 using namespace std; 3 4 class Base 5 { 6 public: 7 Base() 8 { 9 cout << "Create Base" << endl; 10 } 11 ~Base() 12 { 13 cout << "Free Base" << endl; 14 } 15 public: 16 virtual void Show() 17 { 18 cout << "This is Base Show()" << endl; 19 } 20 virtual void Print() 21 { 22 cout << "This is Base Print()" << endl; 23 } 24 void Fun() 25 { 26 cout << "This is Base Fun()" << endl; 27 } 28 private: 29 int x; 30 }; 31 32 class D :public Base 33 { 34 public: 35 D() 36 {} 37 ~D() 38 {} 39 public: 40 void Show() 41 { 42 cout << "This is D Show()" << endl; 43 } 44 void Fun() 45 { 46 cout << "This is D Fun()" << endl; 47 } 48 virtual void List() 49 { 50 cout << "This is D List()" << endl; 51 } 52 private: 53 int y; 54 }; 55 56 void main() 57 { 58 D d; 59 }
虚函数表前后变化
虚函数表在构造父类的时候会记录所有父类的虚函数
这里面少显示了子类的List虚方法,少显示是编译器的问题。但是你不能通过父类指针访问子类List()方法,因为List超出了父类范围。
子类构造完成后,子类重写了父类的虚函数,虚函数表中的虚函。数就变成了子类的。狸猫混太子,偷梁换柱的意思