多态性与前面提到的数据封装和继承性共同构成了面向对象程序设计的三个重要机制。
1.静态联编与动态联编
由于函数重载的存在,当程序中出现调用同名函数时,编译器会根据函数的参数类型、个数决定调用执行哪一个同名函数的代码,这种把一个函数的调用与适当的函数实现代码联系在一起的过程,叫做联编。根据联编的实现阶段的不同,可将其分为静态联编和动态联编两种。
静态联编是在程序编译阶段确定一个函数调用与函数实现代码间的对应关系,这种对应关系确定下来后,在程序运行过程中就根据这个对应关系去调用执行相应的函数代码,并且这种对应关系在程序运行过程中始终保持不变。
而动态联编是在编译阶段不能决定执行哪个同名的被调函数,只在程序运行过程中根据需要处理的对象类型来决定执行哪个类的成员函数。
2.多态性
所谓多态性就是指同样的消息被类的不同对象接收时导致的完全不同的行为的一种现象。这里所说的消息即对类的成员函数的调用。
函数的重载可以实现多态性,但这里要讲的多态性是通过虚函数来实现的,而虚函数又必须存在于继承的环境下。
C++语言支持两种类型的多态:一种是编译时的多态(静态多态),另一种是运行时的多态(动态多态)。在编译时的多态是通过静态联编实现的,而在运行时的多态则是通过动态联编实现的。
3.虚函数
声明虚函数的方法是在基类中的成员函数原型前加上关键字virtual。格式如下:
class 类名{
……
virtual 类型 函数名(参数表);
……
};
当一个类的成员函数声明为虚函数后,这就意味着该成员函数在派生类中可能有不同的实现,也就是说,该函数在派生类中可能需要定义与其基类虚函数原型相同的函数。
虚函数是动态联编的基础,当用基类类型的指针或引用的方法指向不同派生类对象时,系统会在程序运行中根据所指向对象的不同自动选择适当的函数,从而实现了运行时的多态性。
当通过基类指针或引用标识对象并调用成员函数时,由于基类指针可以指向该基类的不同派生类对象,因此存在需要动态联编的可能性,但具体是否使用动态联编,还要看所调用的是否是虚函数。
虚函数可以在一个或多个派生类中被重新定义,但它要求在派生类中重新定义时必须与基类中的函数原型完全相同,包括函数名、返回值类型、参数个数和参数类型的顺序。
只有类的成员函数才能声明为虚函数,但类的构造函数以及全局函数和静态成员函数不能声明为虚函数。
4.用基类指针指向公有派生类对象
指向基类的指针自然可以指向其公有派生类的对象。但是,由于基类指针本身的类型并没有改变,因此,基类指针仅能访问派生类中的基类部分。
5.纯虚函数与抽象类
在定义一个表达抽象概念的基类时,有时可能会无法给出某些成员函数的具体实现。这时,就可以将这些函数声明为纯虚函数。
纯需函数的声明格式如下:
virtual 类型 函数名(参数表)=0;
声明了纯虚函数的基类只是用于继承,仅作为一个接口,具体功能在其派生类中实现。
声明了纯虚函数的类,称为抽象类。抽象类只能用作基类来派生新类,而不能用来创建对象。
系列文章:
C++学习摘要之一:类和对象
C++学习摘要之二:构造函数和析构函数
C++学习摘要之三:继承和派生
C++学习摘要之五:静态成员
C++学习摘要之六:友元函数与友元类
C++学习摘要之七:运算符重载
C++学习摘要之八:模板
C++学习摘要之九:C++流和文件流
版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明!