多态的成立条件
- 有继承
- 子类重写父类虚函数函数
- 返回值,函数名字,函数参数,必须和父类完全一致(析构函数除外)
- 子类中virtual关键字可写可不写,建议写
- 类型兼容,父类指针,父类引用 指向 子类对象
多态分类
- 静态多态 函数重载
- 动态多态 虚函数 继承关系
c++支持编译时多态(静态多态)和运行时多态(动态多态),运算符重载和函数重载就是编译时多态,而派生类和虚函数实现运行时多态。
静态多态和动态多态的区别就是函数地址是早绑定(静态联编)还是晚绑定(动态联编)。如果函数的调用,在编译阶段就可以确定函数的调用地址,并产生代码,就是静态多态(编译时多态),就是说地址是早绑定的。而如果函数的调用地址不能编译不能在编译期间确定,而需要在运行时才能决定,这这就属于晚绑定(动态多态,运行时多态)。
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class Animal { public: virtual void speak() { cout << "动物在叫" << endl; } }; class Cat :public Animal { public: void speak() { cout << "喵喵。。。" << endl; } }; //调用doSpeak, speak函数的地址早就绑定好了, 早绑定(即 静态联编:编译阶段就确定好了地址) //如果想调用猫的speak, 不能提前绑定好函数的地址了,所以需要在运行时再去确定函数地址 //动态联编: 写法 doSpeak绑定的方法改为虚函数 在父类上声明虚函数, 发生了多态 //多态概念:父类的引用或者指针指向子类对象 void doSpeak(Animal& animal) { animal.speak(); } //如果发生了继承关系,编译器允许进行类型转换 void test01() { Cat cat; doSpeak(cat); } int main() { test01(); system("Pause"); return 0; }
结果: