行业知识
【C++】面向对象---多态(万字详解)
2026-11-04 17:39:43
来源:互联网转载
���迎来到小林的博客!!
️博客主页:✈️小林爱敲代码
️文章专栏:✈️小林的C++之路
️欢迎关注:点赞收藏✍️留言
今天给大家讲解多态,多态是面向对象的一个重要内容。也非常的抽象,所以今天尽我所能为大家分享自己对C++中多态的一些理解。
每日一句: 世界上只有想不通的人,没有走不通的路。
大纲:
目录
- 1. 多态的概念
- 2. 多态的定义及实现
- 2.2 多态的构成条件
- 2.3 虚函数
- 2.4 虚函数的重写
- 2.5 协变
- 2.6析构函数的重写
- 2.7 重载,重写(覆盖),重定义(隐藏)之间的区别
- 3. override 和 final(c++11)
- 4.抽象类
- 5.多态的原理
- 6.单继承和多继承的虚函数表
- 6.2 打印虚函数表
- 6.3 单继承的虚函数表
- 6.4 多继承的虚函数表
- 7.多态面试问答题
- 总结:
1. 多态的概念
多态的意思就是多种形态,简而言之就是 : 不同的事物做同一种行为,产生了不同的结果。
打个比方,学生和普通人买票,学生优惠7折,而普通人没有优惠。这类现象就符合多态,不同的事物(普通人,学生)做同一种行为(买票)产生了不同的结果(学生七折,普通人全款)。
而普通人和学生之间还有另外一种关系,那就是继承关系。因为学生也是人,所以构成多态的前提是不同的事物之间构成继承关系。
2. 多态的定义及实现
2.2 多态的构成条件
想要知道多态如何定义,那么我们必须知道多态的定义条件。构成多态的两个条件:
1.必须通过基类的指针或引用调用虚函数。
2.被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。
2.3 虚函数
虚函数:被virtual 修饰的函数即为虚函数。
class Person{public:virtual void BuyTicket()//被virtual修饰,是虚函数{}};2.4 虚函数的重写
虚函数的重写: 派生类必须有一个和基类一样(三同)的虚函数,才能构成重写。构成重写的条件:
1.派生类被重写的函数也得是虚函数(虽然不是也可以,因为会直接继承父类的虚函数)。
2.派生类被重写的函数和基类的虚函数一样 (函数名,返回值,参数都相同,协变除外)。
下面是一个虚函数构成重写的案例:
class Person{public:virtual void BuyTicket(){cout public:virtual void BuyTicket(){cout };class B:public A{};class Person{public:virtual A* BuyTicket(){new A();}};class Student : public Person{public:virtual B* BuyTicket(){new B();}};public:virtual void BuyTicket(){cout cout public:virtual void BuyTicket(){cout cout delete p;}int main(){Person* p = new Person();Student* s = new Student();a(s);return 0;}public:virtual void BuyTicket(){cout cout public:virtual void BuyTicket(){cout cout delete pp;}int main(){Person* p = new Person();Student* s = new Student();a(s);return 0;}public:virtual void Eat() = 0{}};class Student : public Person{public:};int main(){Person p;Student s;return 0;}public:virtual void Eat() = 0{}};class Student : public Person{public:virtual void Eat(){cout Student s;Person& p = s;p.Eat();return 0;}public: void BuyTicket(){ cout public: void BuyTicket(){cout Student s;Person p;return 0;}public:virtual void BuyTicket(){ cout public:virtual void BuyTicket(){cout Student s;Person p;return 0;}public:virtual void fun1(){cout cout public:virtual void fun1(){cout cout cout cout p.fun1();}typedef void(*VFPTR) ();void PrintVTable(VFPTR vTable[]){cout printf(" 第%d个虚函数地址 :0X%x,-", i, vTable[i]);VFPTR f = vTable[i];f();}cout Person p;Student s;VFPTR * vTableb = (VFPTR*)(*(void**)&p);PrintVTable(vTableb);VFPTR* vTabled = (VFPTR*)(*(void**)&s);PrintVTable(vTabled);return 0;}public:virtual void fun1(){cout cout public:virtual void fun1(){cout cout cout cout public:virtual void fun1(){cout cout public:virtual void fun3(){cout cout virtual void fun1(){cout cout cout cout cout printf(" 第%d个虚函数地址 :0X%x,-", i+1, vTable[i]);VFPTR f = vTable[i];f();}cout me m;VFPTR * vTableb = (VFPTR*)(*(void**)&m);PrintVTable(vTableb);VFPTR* vTabled = (VFPTR*)(*(void**)((char*)&m+sizeof(Base1)));PrintVTable(vTabled);return 0;}