• 【C++基础入门】43.C++中多态的概念和意义


    一、函数重写回顾

    • 父类中被重写的函数依然会继承给子类
    • 子类中重写的函数将覆盖父类中的函数
    • 通过作用域分辨符::可以访问到父类中的函数

    二、多态的概念和意义

    • 面向对象中期望的行为
      • 根据实际的对象类型判断如何调用重写函数
      • 父类指针(引用) 指向
        • 父类对象则调用父类中定义的函数
        • 子类对象则调用子类中定义的重写函数
    • 面向对象中的多态的概念
      • 根据实际的对象类型决定函数调用的具体目标
      • 同样的调用语句在实际运行时有多种不同的表现形态

    •  C++ 语言直接支持多态的概念
      • 通过使用 virtual 关键字对多态进行支持
      • virtual 声明的函数被重写后具有多态特性
      • virtual 声明的函数叫做虚函数

            下面看一段多态的代码:

    1. #include
    2. #include
    3. using namespace std;
    4. class Parent
    5. {
    6. public:
    7. virtual void print()
    8. {
    9. cout << "I'm Parent." << endl;
    10. }
    11. };
    12. class Child : public Parent
    13. {
    14. public:
    15. void print()
    16. {
    17. cout << "I'm Child." << endl;
    18. }
    19. };
    20. void how_to_print(Parent* p)
    21. {
    22. p->print(); // 展现多态的行为
    23. }
    24. int main()
    25. {
    26. Parent p;
    27. Child c;
    28. how_to_print(&p); // Expected to print: I'm Parent.
    29. how_to_print(&c); // Expected to print: I'm Child.
    30. return 0;
    31. }

             输出结果如下:

    • 多态的意义
      • 在程序运行过程中展现出动态的特性
      • 函数重写必须多态实现,否则没有意义
      • 多态是面向对象组件化程序设计的基础特性
    • 理论中的概念
      • 静态联编
        • 在程序的编译期间就能确定具体的函数调用
          • 如︰函数重载
      • 动态联编
        • 在程序实际运行后才能确定具体的函数调用
          • 如︰函数重写

            下面看一个动态联编和静态联编的代码,加深对动态联编和静态联编的理解:

    1. #include
    2. #include
    3. using namespace std;
    4. class Parent
    5. {
    6. public:
    7. virtual void func()
    8. {
    9. cout << "void func()" << endl;
    10. }
    11. virtual void func(int i)
    12. {
    13. cout << "void func(int i) : " << i << endl;
    14. }
    15. virtual void func(int i, int j)
    16. {
    17. cout << "void func(int i, int j) : " << "(" << i << ", " << j << ")" << endl;
    18. }
    19. };
    20. class Child : public Parent
    21. {
    22. public:
    23. void func(int i, int j)
    24. {
    25. cout << "void func(int i, int j) : " << i + j << endl;
    26. }
    27. void func(int i, int j, int k)
    28. {
    29. cout << "void func(int i, int j, int k) : " << i + j + k << endl;
    30. }
    31. };
    32. void run(Parent* p)
    33. {
    34. p->func(1, 2); // 展现多态的特性
    35. // 动态联编
    36. }
    37. int main()
    38. {
    39. Parent p;
    40. p.func(); // 静态联编
    41. p.func(1); // 静态联编
    42. p.func(1, 2); // 静态联编
    43. cout << endl;
    44. Child c;
    45. c.func(1, 2); // 静态联编
    46. cout << endl;
    47. run(&p);
    48. run(&c);
    49. return 0;
    50. }

             输出结果如下:

            下面可以再欣赏一个多态代码:

    1. #include
    2. #include
    3. using namespace std;
    4. class Boss
    5. {
    6. public:
    7. int fight()
    8. {
    9. int ret = 10;
    10. cout << "Boss::fight() : " << ret << endl;
    11. return ret;
    12. }
    13. };
    14. class Master
    15. {
    16. public:
    17. virtual int eightSwordKill()
    18. {
    19. int ret = 8;
    20. cout << "Master::eightSwordKill() : " << ret << endl;
    21. return ret;
    22. }
    23. };
    24. class NewMaster : public Master
    25. {
    26. public:
    27. int eightSwordKill()
    28. {
    29. int ret = Master::eightSwordKill() * 2;
    30. cout << "NewMaster::eightSwordKill() : " << ret << endl;
    31. return ret;
    32. }
    33. };
    34. void field_pk(Master* master, Boss* boss)
    35. {
    36. int k = master->eightSwordKill();
    37. int b = boss->fight();
    38. if( k < b )
    39. {
    40. cout << "Master is killed..." << endl;
    41. }
    42. else
    43. {
    44. cout << "Boss is killed..." << endl;
    45. }
    46. }
    47. int main()
    48. {
    49. Master master;
    50. Boss boss;
    51. cout << "Master vs Boss" << endl;
    52. field_pk(&master, &boss);
    53. cout << "NewMaster vs Boss" << endl;
    54. NewMaster newMaster;
    55. field_pk(&newMaster, &boss);
    56. return 0;
    57. }

             输出结果如下:

    三、小结

    • 函数重写只可能发生在父类子类之间

    • 根据实际对象的类型确定调用的具体函数

    • virtual 关键字是 C++ 中支持多态的唯一方式

    • 被重写的虚函数可表现出多态的特性
       

  • 相关阅读:
    【Codeforces】Codeforces Round 905 (Div. 3)
    5分钟搭建一个粗粒度「视频去重」系统
    力扣(LeetCode)181. 超过经理收入的员工(2022.06.29)
    WebSocket 心跳机制如何实现
    自动控制原理3.3---二阶系统的时域分析
    来实现一个DataStore的封装吧
    Debezium日常分享系列之:Debezium 2.3.0.Final发布
    什么是数据标注?
    基于文化算法优化的神经网络预测研究(Matlab代码实现)
    【深入浅出Spring原理及实战】「夯实基础系列」360全方位渗透和探究Spring配置开发实战详解
  • 原文地址:https://blog.csdn.net/weixin_43129713/article/details/134045708