都说c++的三大特性是 继承 多态 封装
那么什么是多态呢?
1、静态多态:函数重载、运算符重载、复用函数名。
2、动态多 态:派生类和虚函数实现运行时的多态。
其实这俩个就是地址早晚绑定的区别
下面来看
静态多态不用细说,下面介绍动态多态。
首先c++时允许父子类型转换如下
#includeusing namespace std; class animal { public: void speak() { cout << "这是动物在说话" << endl; } }; class dog :public animal { public: void speak() { cout << "这是小狗在说话" << endl; } }; void text01(animal &a)//animal &a=d; { a.speak(); } int main() { dog d; text01(d); return 0; }
这样编译是没有问题的,但是你们觉得输出的是什么呢?
没错就是
但是我们的原意好像是想让小狗在说话吧,但是现在这个函数的地址其实就在编译阶段地址就绑定成动物的了,并不是小猫的,哪接下来如果想实现地址在运行时绑定地址怎么办呢,就是在父类函数前加一个virtual (简称虚函数)
#includeusing namespace std; class animal { public: virtual void speak() { cout << "这是动物在说话" << endl; } }; class dog :public animal { public: virtual void speak()//这里的virtual可加可不加,因为是继承父类的函数现在只是重写函数的功能 { cout << "这是小狗在说话" << endl; } }; void text01(animal &a) { a.speak(); } int main() { dog d; text01(d); return 0; }
现在我们任务就完成了
现在动态多态的满足条件就是
1、有继承关系
2、子类要重写父类的虚函数(重写就是函数返回值,参数列表都相同,只有函数内部东西不一样才叫重写)
动态多态的使用
1、父类的指针或着引用执行之类对象,就是上面函数那样。
原理剖析
#includeusing namespace std; class animal { public: void speak() { cout << "这是动物在说话" << endl; } }; int main() { animal a; cout << sizeof(a) << endl; return 0; }
因为类内部的函数存储位置和数据类型存储不一样,所以这个算是空类占的内存就是1
那么加上virtual呢
#includeusing namespace std; class animal { public: virtual void speak() { cout << "这是动物在说话" << endl; } }; int main() { animal a; cout << sizeof(a) << endl; return 0; }
显然这个类里已经有了一个4个字节的东西,一般什么是4个字节?int?float?还有一个指针也是4个字节。那这么高级的东西,里面肯定就是一个指针了。
其实就是函数内部出现了一个vfptr(虚函数指针)用来间接指向这个函数,相当于
class animal { public: vfptr(这是一个指针)-> 指向一个vftable(虚函数表) }; vftable { &animal::speak(这个就是我们写的函数的地址) 就是一个指针指向一个内存里,这个内存存的就是我们写的虚函数的地址 }现在加上子类
class animal { public: virtual void speak() { cout << "这是动物在说话" << endl; } }; class dog :public animal { public: }; dog { vfptr->vftable 如果没有重写那么就是继承父类的一切东西 } vftable { &animal::speak(这个就是我们写的函数的地址) 就是一个指针指向一个内存里,这个内存存的就是我们写的虚函数的地址 } 重写之后 class dog :public animal { public: void speak() { cout << "这是小狗在说话" << endl; } }; vftable { &dog::speak(这个就是我们写的函数的地址) 就是一个指针指向一个内存里,这个内存存的就是我们写的虚函数的地址 }当父类指针或者引用指向子类对象的话,就发生了多态。
现在你已经学会了多态,是不是非常简单。



