静态联编和动态联编
联编是指⼀个计算机程序⾃⾝彼此关联的过程,在这个联编过程中,需要确定程序中的操作调⽤(函数调⽤)与执⾏该操作(函数)的代码段之间
的映射关系;按照联编所进⾏的阶段不同,可分为静态联编和动态联编;
静态联编:
是指联编⼯作是在程序编译连接阶段进⾏的,这种联编⼜称为早期联编;因为这种联编是在程序开始运⾏之前完成的;
多态性与虚函数
在程序编译阶段进⾏的这种联编⼜称静态束定;在编译时就解决了程序中的操作调⽤与执⾏该操作代码间的关系,确定这种关系⼜被称为束定;编译时束定⼜称为静态束定;
动态联编:
编译程序在编译阶段并不能确切地知道将要调⽤的函数,只有在程序执⾏时才能确定将要调⽤的函数,为此要确切地知道将要调⽤的函数,要求联编⼯作在程序运⾏时进⾏,这种在程序运⾏时进⾏的联编⼯作被称为动态联编,或动态束定,⼜叫晚期联编;C++规定:动态联编是在虚函数的⽀持下实现的;
静态联编和动态联编都是属于多态性的,它们是在不同的阶段进对不同的实现进⾏不同的选择;
虚函数是动态联编的基础;虚函数是成员函数,⽽且是⾮静态的成员函数;虚函数在派⽣类中可能有不同的实现,当使⽤这个成员函数操作指针或引⽤所标识的对象时,对该成员函数的调⽤采⽤动态联编⽅式,即:在程序运⾏时进⾏关联或束定调⽤关系;
动态联编只能通过指针或引⽤标识对象来操作虚函数;如果采⽤⼀般的标识对象来操作虚函数,将采⽤静态联编的⽅式调⽤虚函数;
如果⼀个类具有虚函数,那么编译器就会为这个类的对象定义⼀个指针成员,并让这个指针成员指向⼀个表格,这个表格⾥⾯存放的是类的虚函数的⼊⼝地址;⽐如:⼀个基类⾥⾯有⼀些虚函数,那么这个基类就拥有这样⼀个表,它⾥⾯存放了⾃⼰的虚函数的⼊⼝地址,其派⽣类继承了这个虚函数表,如果在派⽣类中重写/覆盖/修改了基类中的虚函数,那么编译器就会把虚函数表中的函数⼊⼝地址修改成派⽣类中的对应虚函数的⼊⼝地址;这就为类的多态性的实现提供了基础;
虚函数按照其声明顺序存放于虚函数表中;
⽗类的虚函数存放在⼦类虚函数的前⾯;
多继承中,每个⽗类都有⾃⼰的虚函数表;
⼦类的成员函数被存放于第⼀个⽗类的虚函数表中;
虚函数表:Virtual Function Table;
虚函数表指针:Virtual Function Table Pointer(VFT-PTR);
虚基类表:Virtual BaseClass Table;
虚基类表指针:Virtual BaseClass Pointer(VBT-PTR);确切地说,应该是虚基类指针表;
附带上⼀些图⽚: