• c++ 继承与多态


    一、c++如何解决菱形继承的问题

    例子一

    菱形继承问题

    1. #include
    2. #include
    3. using namespace std;
    4. class Animal
    5. {
    6. public:
    7. int m_Age;
    8. };
    9. class Sheep : public Animal {};
    10. class Tuo : public Animal {};
    11. class SheepTuo :public Sheep, public Tuo
    12. {
    13. public:
    14. };
    15. void test()
    16. {
    17. SheepTuo st;
    18. st.Sheep::m_Age = 100;
    19. st.Tuo::m_Age = 200;
    20. cout << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
    21. cout << "st.Tuo::m_Age = " << st.Tuo::m_Age << endl;
    22. cout << "st.m_Age = " << st.m_Age << endl;//err
    23. }
    24. void main()
    25. {
    26. test();
    27. }

     

     例子二

    解决菱形继承的问题

    1. #include
    2. #include
    3. using namespace std;
    4. class Animal
    5. {
    6. public:
    7. int m_Age;
    8. };
    9. class Sheep :virtual public Animal {};
    10. class Tuo :virtual public Animal {};
    11. class SheepTuo :public Sheep, public Tuo
    12. {
    13. public:
    14. };
    15. void test()
    16. {
    17. SheepTuo st;
    18. st.Sheep::m_Age = 100;
    19. st.Tuo::m_Age = 200;
    20. cout << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
    21. cout << "st.Tuo::m_Age = " << st.Tuo::m_Age << endl;
    22. cout << "st.m_Age = " << st.m_Age << endl;//err
    23. }
    24. void main()
    25. {
    26. test();
    27. }

    二、c++中的多态

    多态的分类
    1、静态多态:函数重载与运算符重载(本质可以裂解为函数重载)都属于静态多态,复用函数名
    2、动态多态:派生类和虚函数实现运行时多态

     静态多态与动态多态的区别:
    1、静态多态的函数地址早绑定 - 编译阶段确定函数地址
    2、动态多态的函数地址晚绑定 - 运行阶段确定函数地址(利用virtual关键字)
     

    例子一

    继承,编译阶段即确定调用的函数

    1. #include <iostream>
    2. #include <string.h>
    3. using namespace std;
    4. //多态的分类
    5. //1、静态多态:函数重载与运算符重载(本质可以裂解为函数重载)都属于静态多态,复用函数名
    6. //2、动态多态:派生类和虚函数实现运行时多态
    7. //
    8. // 静态多态与动态多态的区别:
    9. //1、静态多态的函数地址早绑定 - 编译阶段确定函数地址
    10. //2、动态多态的函数地址晚绑定 - 运行阶段确定函数地址(利用virtual关键字)
    11. //
    12. class Animal
    13. {
    14. //这里是地址早绑定,静态绑定
    15. public:
    16. void speak()
    17. {
    18. cout << "Animal speak" << endl;
    19. }
    20. };
    21. class Cat :public Animal
    22. {
    23. public:
    24. void speak()
    25. {
    26. cout << "Cat speak" << endl;
    27. }
    28. };
    29. class Dog :public Animal
    30. {
    31. public:
    32. void speak()
    33. {
    34. cout << "Dog speak" << endl;
    35. }
    36. };
    37. //无论传入的是cat对象还是dog对象,执行的都是Animal的speak方法,这里是地址早绑定,静态绑定
    38. //编译阶段就确定了调用方法
    39. void doSpeak(Animal& animal)
    40. {
    41. animal.speak();
    42. }
    43. void test()
    44. {
    45. Cat cat;
    46. Dog dog;
    47. doSpeak(dog);
    48. }
    49. void main()
    50. {
    51. test();
    52. }

    例子二

    利用virtual,虚函数的概念,动态绑定调用的函数

    1. #include
    2. #include
    3. using namespace std;
    4. //多态的分类
    5. //1、静态多态:函数重载与运算符重载(本质可以裂解为函数重载)都属于静态多态,复用函数名
    6. //2、动态多态:派生类和虚函数实现运行时多态
    7. //
    8. // 静态多态与动态多态的区别:
    9. //1、静态多态的函数地址早绑定 - 编译阶段确定函数地址
    10. //2、动态多态的函数地址晚绑定 - 运行阶段确定函数地址(利用virtual关键字)
    11. //
    12. class Animal
    13. {
    14. //这里是地址早绑定,静态绑定
    15. public:
    16. virtual void speak()
    17. {
    18. cout << "Animal speak" << endl;
    19. }
    20. };
    21. class Cat :public Animal
    22. {
    23. public:
    24. //这里子类(派生类)的virtual可以省略 override表示复写积累中的方法
    25. virtual void speak() override
    26. {
    27. cout << "Cat speak" << endl;
    28. }
    29. };
    30. class Dog :public Animal
    31. {
    32. public:
    33. void speak()
    34. {
    35. cout << "Dog speak" << endl;
    36. }
    37. };
    38. //根据传入的对象cat对象还是dog对象,来决定执行的都是Cat的speak方法,还是Dog的speak方法
    39. //这里是函数地址晚绑定,动态绑定
    40. //运行阶段确定调用方法
    41. void doSpeak(Animal& animal)
    42. {
    43. animal.speak();
    44. }
    45. void test()
    46. {
    47. Cat cat;
    48. Dog dog;
    49. doSpeak(dog);
    50. }
    51. void main()
    52. {
    53. test();
    54. }

    c++多态的原理

    下图中的vfprt都是同一个指针,子类会继承父类的虚函数指针与虚函数表,如果发生了子类覆写了父类的virtual的方法,则会子类中的虚函数表的方法会替换成子类的方法指针

     

  • 相关阅读:
    9.30~10.5新生赛C~J题
    压力传感器、液位传感器在消防中的使用
    全图化在线系统设计
    leetcode986. 区间列表的交集
    linux免密登录
    Android-AGP之手写你的第一款自定义plugin插件
    OpenResty“更好更灵活的 Nginx”,这份OpenResty开发指南你值得拥有
    steam搬砖项目,csgo游戏搬砖熟练操作后,可以月入过万~
    【实战】学习 Electron:构建跨平台桌面应用
    【IEEE出版】工业自动化,机器人与控制工程国际会议(IARCE 2022)
  • 原文地址:https://blog.csdn.net/lengyue1084/article/details/133089266