• 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.多态:父类的指针或引用指向子类对象        

  • 相关阅读:
    Flink多流转换(一)
    CMSIS-RTOS在stm32使用
    TensorRT c++部署onnx模型
    Linux常用命令
    我与java的第一次相识
    软件测试/测试开发丨明确的编码规范,避免冗余和混乱
    Flink对比Spark
    灵茶八题 题目解析+核心代码
    docker 中安装 MySQL 以及使用
    mysql高阶语句
  • 原文地址:https://blog.csdn.net/qq_41583263/article/details/127405223