• 38. 多态中的静态联编和动态联编


            首先看个例子:

            在类外进行创建的函数speak函数,引用的明明是Animal类,可是为什么speak中的参数为Dog类时依然没有报错?
            这是因为如果发生了继承的关系,编译器允许进行类型转换!!!

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include
    3. using namespace std;
    4. class Animal
    5. {
    6. public:
    7. void speak()
    8. {
    9. cout << "动物叫" << endl;
    10. }
    11. };
    12. class Dog :public Animal
    13. {
    14. public:
    15. void speak()
    16. {
    17. cout << "汪汪汪" << endl;
    18. }
    19. };
    20. //调用speak,speak函数的地地址早就绑定好了,即Animal类中的speak函数的地址
    21. void speak(Animal& animal) //类外创建的speak函数,参数为Animal类的引用
    22. {
    23. animal.speak();
    24. }
    25. //在这里注意:我们明明创建的是Animal类的引用,可是为什么speak中的参数为Dog类时依然没有报错?
    26. //这是因为如果发生了继承的关系,编译器允许进行类型转换!!!
    27. void test()
    28. {
    29. Dog dog;
    30. speak(dog);
    31. }
    32. int main()
    33. {
    34. test();
    35. return 0;
    36. }

    在运行以后会输出什么结果呢?

    为什么是动物叫而不是汪汪汪呢? 

            这是因为早在编译阶段就已经将要调用的函数的地址确定了,调用speak,speak函数的地址早就绑定Animal类中的speak函数的地址,即静态联编

    那么怎么才能让调用speak函数以后让狗叫呢?

            这时需要在运行的时候去确定函数地址,即动态联编,将Animal类中的speak函数改为虚函数,语法:在前面加virtual关键词就行

    代码如下:

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include
    3. using namespace std;
    4. class Animal
    5. {
    6. public:
    7. virtual void speak()
    8. {
    9. cout << "动物叫" << endl;
    10. }
    11. };
    12. class Dog :public Animal
    13. {
    14. public:
    15. void speak()
    16. {
    17. cout << "汪汪汪" << endl;
    18. }
    19. };
    20. void speak(Animal& animal) //类外创建的speak函数,参数为Animal类的引用
    21. {
    22. animal.speak();
    23. }
    24. // 在这里注意:我们明明创建的是Animal类的引用,可是为什么speak中的参数为Dog类时依然没有报错?
    25. //这是因为如果发生了继承的关系,编译器允许进行类型转换!!!
    26. void test()
    27. {
    28. Dog dog;
    29. speak(dog);
    30. }
    31. int main()
    32. {
    33. test();
    34. return 0;
    35. }

    运行结果:

     在父类上声明虚函数,就发生了多态!即父类的指针或引用指向子类对象

    多态的分类:

            1.静态多态: 函数重载

            2.动态多态: 虚函数 

            3.静态联编: 地址早绑定,编译阶段就绑定好地址

            4.动态联编: 地址晚绑定,运行时绑定好地址

            5.多态:父类的指针或引用指向子类对象        

  • 相关阅读:
    你犯过程序员容易犯的这些错误吗?快来看看!
    解决 WSL 与 Windows 交互问题
    灰色关联分析
    AR工业眼镜:智能化生产新时代的引领者!!
    C++的线性回归模型
    称砝码【set】
    探索“科技助实”,上海交通大学、蚂蚁集团等发起第三届ATEC科技精英赛
    C++菱形继承问题与虚拟继承原理
    一键安装|卸载 mysql 8.2.0 shell脚本
    4.任务调度
  • 原文地址:https://blog.csdn.net/qq_41583263/article/details/127405223