• C++零碎记录(十三)


    23. 多态

    23.1 多态简介

    ① 多态是C++面向对象三大特性之一。

    ② 多态分为两类:

    1. 静态多态:函数重载和运算符重载属于静态多态,复用函数名。
    2. 动态多态:派生类和 虚函数实现运行时多态。

    ③ 静态多态和动态多态区别:

    1. 静态多态的函数地址早绑定,编译阶段确定函数地址。
    2. 动态多态的函数地址晚绑定,运行阶段确定函数地址。

    ④ 多态满足条件:

    1. 有继承关系
    2. 子类重写父类中的虚函数

    ④ 多态使用条件:

    1. 父类指针或引用指向子类对象

    ⑤ 重写:函数返回值类型、函数名、参数列表都完全一致称为重写。

    23.2 多态地址绑定

    23.2.1 地址早绑定

    1. #include <iostream>
    2. using namespace std;
    3. //多态
    4. //动物类
    5. class Animal
    6. {
    7. public:
    8. void speak()
    9. {
    10. cout << "动物在说话" << endl;
    11. }
    12. };
    13. //猫类
    14. class Cat:public Animal
    15. {
    16. public:
    17. void speak()
    18. {
    19. cout << "小猫在说话" << endl;
    20. }
    21. };
    22. //执行说话的函数
    23. //地址早绑定 在编译阶段确定函数地址
    24. //如果想执行让猫说话,那么这个函数就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定
    25. void doSpeak(Animal &animal) // Animal & animal = cat
    26. {
    27. animal.speak();
    28. }
    29. void test01()
    30. {
    31. Cat cat;
    32. doSpeak(cat);
    33. }
    34. int main()
    35. {
    36. test01();
    37. system("pause");
    38. return 0;
    39. }

    运行结果:

    • 动物在说话
    • 请按任意键继续. . .

    23.2.2 地址晚绑定虚函数

    1. #include <iostream>
    2. using namespace std;
    3. //多态
    4. //动物类
    5. class Animal
    6. {
    7. public:
    8. virtual void speak()
    9. {
    10. cout << "动物在说话" << endl;
    11. }
    12. };
    13. //猫类
    14. class Cat:public Animal
    15. {
    16. public:
    17. //重写 函数返回值类型、函数名、参数列表都完全相同才叫重写
    18. void speak() //子类virtual可写可不写,也可以写 virtual void speak()
    19. {
    20. cout << "小猫在说话" << endl;
    21. }
    22. };
    23. //狗类
    24. class Dog:public Animal
    25. {
    26. public:
    27. virtual void speak()
    28. {
    29. cout << "小狗在说话" << endl;
    30. }
    31. };
    32. //执行说话的函数
    33. //地址早绑定 在编译阶段确定函数地址
    34. //如果想执行让猫说话,那么这个函数就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定
    35. //动态多态满足条件
    36. //1、有继承关系
    37. //2、子类重写父类的虚函数
    38. //动态多态使用
    39. //父类的引用或指针指向子类对象
    40. void doSpeak(Animal &animal) // Animal & animal = cat
    41. {
    42. animal.speak();
    43. }
    44. void test01()
    45. {
    46. Cat cat;
    47. doSpeak(cat);
    48. Dog dog;
    49. doSpeak(dog);
    50. }
    51. int main()
    52. {
    53. test01();
    54. system("pause");
    55. return 0;
    56. }

    运行结果:

    • 小猫在说话
    • 小狗在说话
    • 请按任意键继续. . .

    23.3 多态的原理剖析

    ① 当没有发生重写时,子类中的虚函数表内部为父类的虚函数地址。

    ② 当子类重写父类的虚函数,子类中的虚函数表内部会替换成子类的虚函数地址。

    1. #include <iostream>
    2. using namespace std;
    3. //多态
    4. //动物类
    5. class Animal
    6. {
    7. public: //如果是虚函数,那么类里面存了一个指针,类占4个字节
    8. virtual void speak() //如果是非静态成员函数void speak(),那么函数不在类上,空类占1个字节空间
    9. {
    10. cout << "动物在说话" << endl;
    11. }
    12. };
    13. //猫类
    14. class Cat:public Animal
    15. {
    16. public:
    17. void speak()
    18. {
    19. cout << "小猫在说话" << endl;
    20. }
    21. };
    22. //狗类
    23. class Dog:public Animal
    24. {
    25. public:
    26. virtual void speak()
    27. {
    28. cout << "小狗在说话" << endl;
    29. }
    30. };
    31. //执行说话的函数
    32. //地址早绑定 在编译阶段确定函数地址
    33. //如果想执行让猫说话,那么这个函数就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定
    34. //动态多态满足条件
    35. //1、有继承关系
    36. //2、子类重写父类的虚函数
    37. //动态多态使用
    38. //父类的引用或指针指向子类对象
    39. void doSpeak(Animal &animal) // Animal & animal = cat
    40. {
    41. animal.speak();
    42. }
    43. void test01()
    44. {
    45. Cat cat;
    46. doSpeak(cat);
    47. Dog dog;
    48. doSpeak(dog);
    49. }
    50. void test02()
    51. {
    52. cout << "sizeof Animal = " << sizeof(Animal) << endl;
    53. }
    54. int main()
    55. {
    56. //test01();
    57. test02();
    58. system("pause");
    59. return 0;
    60. }

    运行结果:

    • sizeof Animal = 4
    • 请按任意键继续. . .

    链接:https://www.zhihu.com/question/437657370/answer/1692846096
     

  • 相关阅读:
    极限导论总结
    计算机网络【第一章】
    用cpolar发布Ubuntu上的网页(1)
    SpringBoot整合quartz实现定时任务
    C++继承相关应用练习
    深度学习 opencv python 实现中国交通标志识别 计算机竞赛_1
    通过关键词合并2张excel表格——Python代码实现
    微信小程序之生成二维码
    Spring 对 Java EE API 整合-5
    Github每日精选(第68期):HTTP客户端哪家强-reqwest
  • 原文地址:https://blog.csdn.net/qq18218628646/article/details/132845551