多态

来源:互联网 发布:aⅴ淘宝2016 编辑:程序博客网 时间:2024/06/08 17:12

多态性是面向对象设计语言的基本特征之一。多态性是面向对象的精髓。多态性可以简单地概括为“一个接口,多种方法”

多态性是指同一个操作作用于不同的对象就会产生不同的响应;多态性分为静态多态性和动态多态性,其中函数重载和运算符重载属于静态多态性, 虚函数属于动态多态性。


程序调用函数时,具体应使用哪个代码块是由编译器决定的。以函数重载为例,C++编译器根据传递给函数的参数和函数名决定具体要使用哪一个函数,称为联编(binding)。
编译器可以在编译过程中完成这种联编,在编译过程中进行的联编叫静态联编(static binding)或早期联编(early binding)。如:函数重载和运算符重载


在一些场合下,编译器无法在编译过程中完成联编,必须在程序运行时完成选择,因此编译器必须提供这么一套称为“动态联编”(dynamic binding)的机制,也叫晚期联编(late binding),C++通过虚函数来实现动态联编


虚函数的定义很简单,只要在成员函数原型前加一个关键字virtual即可。
如果一个基类的成员函数定义为虚函数,那么,它在所有派生类中也保持为虚函数;即使在派生类中省略了virtual关键字,也仍然是虚函数。
派生类要对虚函数进行中可根据需重定义,重定义的格式有一定的要求:
与基类的虚函数有相同的参数个数;
与基类的虚函数有相同的参数类型;
与基类的虚函数有相同的返回类型。


通过指针访问disp():
不加virtual时,具体调用哪个版本的disp()只取决于指针本身的类型,和指针所指对象的类型无关。
而加virtual时,具体调用哪个版本的disp()不再取决于指针本身的类型,而是取决于指针所指对象的类型。

虚函数的实现原理:虚函数表

如果一个基类中有一个虚函数,在创建对象时,会在对象的存储布局的首地址有一个虚函数指针,该虚函数指针指向一个虚函数表,虚函数表之中存放的是虚函数的入口地址,通过该入口地址就能找到相应的函数。

虚函数特效被激活的时机:
>基类之中定义了一个或者几个虚函数,派生类之中也覆盖了这几个虚函数
>通过一个基类指针或者引用指向派生类对象
>最后通过指针或者引用调用虚函数

访问:对象名来访问(取决于对象名类型)

           指针访问(指针所指的对象)

           引用访问(一经引用,调用函数就不能改变)


#include <iostream>using std::cout;using std::endl;class Base{public:virtual void display(){cout << "Base::display()" << endl;}private:double _dx;};class Child1 : public Base{public:void display(){cout << "Child1::display()" << endl;}};class Child2 : public Base{public:void display(){cout << "Child2::display()" << endl;}};//虚函数机制被激活的时机://1. 基类定义了虚函数,派生类覆盖了基类的虚函数//2.  通过一个基类的指针或者引用指向了派生类对象//3.  通过该指针或引用调用虚函数void display(Base * pbase){pbase->display();}int main(void){cout << " sizeof(Base) = " << sizeof(Base) << endl;cout << " sizeof(Child1) = " << sizeof(Child1) << endl;cout << " sizeof(Child2) = " << sizeof(Child2) << endl;Base base;Child1 child1;Child2 child2;display(&base);display(&child1);display(&child2);cout << endl;base.display();//采用对象名的方式进行访问,虚函数并不表现出虚函数的特性child1.display();//直接去方法区找相应的函数child2.display();//体现的是隐藏,隐藏基类相应的方法cout << endl;Base & ref = child1;ref.display();return 0;}




0 0
原创粉丝点击