程序关联的两种方式
1、静态关联
关联工作在编译、链接阶段完成的情况称为静态关联。因为关联过程是在程序编译。链接期间完成的,因此有时也称早期关联或提前关联。在编译、链接过程中,系统就可以根据函数的参数类型或是个数等特征进行匹配后,确定要调用若干名函数中的哪一个。一般情况下,函数重载和运算符重载都属于静态关联。
静态关联的主要优点是程序执行效率高,因为在编译、链接阶段有关函数调用和具体的执行代码的关系已经确定,所以执行速度快。
但是,静态关联也存在缺点,它需要程序员必须预测在每一种情况下所有的函数调用中将要使用的那些对象,这无形中增加了编程的负担。
2、动态关联
和静态关联对应,关联工作在程序运行阶段完成的情况称为动态关联,也称晚期关联或滞后关联。在编译、链接过程中无法解决的关联问题,可以等到程序开始运行滞后再来确定关联那个具体的函数。也就是说,只有运行时,向具有多态性的函数传递一个实际对象时,该函数名的调用才能与若干个同名函数中的某一个函数关联起来。
动态关联的主要优点是提供了更好的编程灵活性、问题抽象性和程序的易维护性,但是与静态关联相比,函数调用速度慢,因为动态关联需要在程序运行过程中搜索以确定函数调用(消息)与程序代码(方法)之间的匹配关系。
虚函数
虚函数的定义是在基类中进行的,它是在需要定义为虚函数的成员函数的声明前冠以关键字virtual,并在派生类中对这个函数进行重新定义。
在类的成员函数声明前加关键字virtual。格式如下:
virtual 函数类型 函数名(参数表)
{
函数体;
}
如果在派生类中的函数满足以下三个条件,则可以判断该函数时虚函数:
1、该函数与基类的虚函数有相同的名称。
2、该函数与基类的虚函数有相同的参数个数及相同的对应参数类型。
3、该函数与基类的虚函数有相同的返回类型或者满足赋值兼容规则的指针、引用型。
注意:当虚函数的参数列表中存在默认参数时,极易出错。因为虚函数是动态绑定的,默认参数时静态绑定的。
如何利用虚函数实现运行时的多态性
方法:在基类中声明一个虚函数,在此基类的派生类中定义与虚函数相同原型的虚函数,这些虚函数同名同原型,但实现的功能即代码不同,需要实现哪个对象的虚函数的功能,就用基类指针变量在运行中动态地指向要实现功能的那个派生类对象,通过调用同一函数名(接口),在运行中动态地选择不同的实现代码而实现不同的功能。一般形式为:
基类指针变量 = 某派生类对象指针;
基类指针变量 ->虚函数(参数列表);
内部实现上,如果在基类中声明某个虚函数,则表示通知编译系统,此函数名在编译阶段不予某一具体函数代码绑定(即不进行静态关联)(由于尚不是一个具体的函数,故声明为虚函数,代表几个相同原型而不同函数体的函数),留待运行时根据需要(将相应对象的指针赋予基类指针变量)临时选择(动态绑定)一个派生类中与其原型相同的函数去执行,从而实现运行时的多态性。
注意:内联函数不能是虚函数,因为内联函数是不能在运行时动态确定其位置的。即使虚函数是在类的内部 定义,编译时仍将其看作是非内联。构造函数不能是虚函数,因为虚函数作为运行过程中多态的基础,主要是针对对象的,而构造函数是在对象产生之前运行的,所以虚构造函数是没有意义的。析构函数可以是虚函数,而且通常被声明为虚函数。