多态性是容许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值以后,父对象就能够根据当前赋值给它的子对象的特性以不一样的方式运做。简单的说:容许将子类类型的指针赋值给父类类型的指针(一个接口,多种方法)。
C++ 支持两种多态性:编译时多态性,运行时多态性。
a、编译时多态性(静态多态):经过重载函数实现
b、运行时多态性(动态多态):经过虚函数实现。git
那么多态的做用是什么呢,封装可使得代码模块化,继承能够扩展已存在的代码,他们的目的都是为了代码重用。而多态的目的则是为了接口重用。也就是说,不论传递过来的到底是那个类的对象,函数都可以经过同一个接口调用到适应各自对象的实现方法。github
运行时多态:ide
最多见的用法就是声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,能够根据指向的子类的不一样而实现不一样的方法。若是没有使用虚函数的话,则利用基类指针调用相应的函数的时候,将总被限制在基类函数自己,而没法调用到子类中被重写过的函数。由于没有多态性,函数调用的地址将是必定的,而固定的地址将始终调用到同一个函数,这就没法实现一个接口,多种方法的目的了。模块化
非运行时多态:函数
经过函数重载实现spa
简而言之:指针
隐藏是指派生类的函数屏蔽了与其同名的基类函数,规则以下:code
虚函数: 就是容许被其子类从新定义的成员函数,子类从新定义父类虚函数的作法,可实现成员函数的动态覆盖(Override)。对象
纯虚函数: 是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义本身的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”
virtual void funtion()=0
抽象类: 包含纯虚函数的类称为抽象类。因为抽象类包含了没有定义的纯虚函数,因此不能进行实例化。
纯虚函数的做用:
virtual ReturnType Function()= 0;
),则编译器要求在派生类中必须予以重写以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。示例代码:
#include<iostream> using namespace std; //基类对象 class Base { public: //有virtual关键字,运行时多态 virtual void f(float x) { cout<<"Base::f(float)"<< x <<endl; } //无viratul关键字,不会发生运行时多态 void g(float x) { cout<<"Base::g(float)"<< x <<endl; } void h(float x) { cout<<"Base::h(float)"<< x <<endl; } }; class Derived : public Base { public: virtual void f(float x) { cout<<"Derived::f(float)"<< x <<endl; //多态、覆盖 } //子类与父类的函数同名,无virtual关键字,则为隐藏 void g(int x) { cout<<"Derived::g(int)"<< x <<endl; //隐藏 } void h(float x) { cout<<"Derived::h(float)"<< x <<endl; //隐藏 } }; int main(void) { Derived d; //子类 Base *pb = &d; //基类指针指向子类 Derived *pd = &d; //子类指针指向本身 // Good : behavior depends solely on type of the object pb->f(3.14f); // Derived::f(float) 3.14 调用子类,多态 pd->f(3.14f); // Derived::f(float) 3.14 调用子类 // Bad : behavior depends on type of the pointer pb->g(3.14f); // Base::g(float) 3.14 无多态,调用本身的 pd->g(3.14f); // Derived::g(int) 3 无多态,调用本身的 // Bad : behavior depends on type of the pointer pb->h(3.14f); // Base::h(float) 3.14 无多态,调用本身的 pd->h(3.14f); // Derived::h(float) 3.14 无多态,调用本身的 return 0; }