zoukankan      html  css  js  c++  java
  • C++ 多态、虚函数(virtual 关键字)、静态联编、动态联编

    函数重写:(在子类中重写父类中的函数)

      父类中被重写的函数  依然会继承  给子类。

      子类中重写的函数将覆盖父类中的函数

      通过作用域分辨符  ::  可以访问到父类中的函数

      例如:

      

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    
    class parent
    {
        public:
                void parent_func(int i , int j)
                    {
                        cout << "parent_func(int i , int j)"<<i<<','<<j<<endl;
                    }
    };
    
    class subClass : public parent
    {
        public:
                void parent_func(int i , int j)//重写父类中的  void parent_func(int i , int j)
                    {
                        cout << "parent_func(int i , int j)"<<i*2<<','<<j*2<<endl;
                    }
    };
    
    
    
    void doPrint(parent *p)//如果是 subClass 声明的对象,将把 subClass类退化为 parent类来处理(C++ 默认)
    {
        p->parent_func(1, 2);
    }
    int main()
    {
        parent p;
        subClass s;
    
        s.parent::parent_func(1,5);//使用作用域分辨符 通过subClass 声明的对象 去调用parent类中的 parent_func(int i , int j)函数
    
        doPrint(&p);//使用  parent类对象
        doPrint(&s);//使用subClass类对象
    }
        

    运行结果:  

    parent_func(int i , int j)1,5
    parent_func(int i , int j)1,2
    parent_func(int i , int j)1,2

    面向对象期望的行为:

      根据实际的对象类型判断如何调用重写函数

    父类指针(引用)指向

      父类对象则调用父类中定义的函数

      子类对象则调用  子类中  重写 的函数

     也就是说期望  void doPrint(parent *p) 这个函数调用的时候,如果是父类的对象则直接调用父类中的  void parent_func(int i , int j) 输出结果为:parent_func(int i , int j)1,2

      如果是子类对象 则调用void parent_func(int i , int j) 输出结果为:parent_func(int i , int j)2,4

    就需要在 父类中将void parent_func(int i , int j)  改为:virtual void parent_func(int i , int j)  表明此函数为   虚函数   子类通过继承的关系 也将把void parent_func(int i , int j)  修改为  虚函数

      -通过virtual 支持多态(C++ 中实现多态的唯一方法)

      -被virtual 声明的函数被重写后具备多态的特性

      -被virtual 关键字声明的函数叫做虚函数。

      修改代码如下:  

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    
    class parent
    {
        public:
                virtual void parent_func(int i , int j)
                    {
                        cout << "parent  parent_func(int i , int j)"<<i<<','<<j<<endl;
                    }
    };
    
    class subClass : public parent
    {
        public:
                void parent_func(int i ,int j)//重写父类中的  void parent_func(int i , int j)
                    {
                        cout << "subClass parent_func(int i , int j)"<<i*2<<','<<j*2<<endl;
                    }
    };
    
    
    
    void doPrint(parent *p)
    {
        p->parent_func(1, 2); //根据对象类型判断如何调用重写函数。
    }
    int main()
    {
        parent p;
        subClass s;
    
    
    
        doPrint(&p);//使用  parent类对象
        doPrint(&s);//使用subClass类对象
    }
        

    运行结果:  

    parent  parent_func(int i , int j)1,2
    subClass parent_func(int i , int j)2,4

    多态存在的意义:

      -多态在程序运行的过程中展现

      -函数重写必须实现多态,否则无意义

      -是面向对象 组件化程序设计  的基础特性

    静态联编:

      在编译的期间就确定了具体的函数调用(重载函数)

    动态联编:

      在程序运行后才能确定函数的调用(重写函数)

    例如:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    
    class parent
    {
        public:
                virtual void func(int i )
                    {
                        cout << "func(int i )"<<i<<endl;
                    }
                virtual void func(int i , int j)
                    {
                        cout << "parent  func(int i , int j)"<<i<<','<<j<<endl;
                    }
                virtual void func(int i , int j,int k)
                    {
                        cout << "parent  func(int i , int j,int k)"<<i<<','<<j<<','<<'k'<<endl;
                    }
    };
    
    class subClass : public parent
    {
        public:
                 void func(int i , int j)  //等价于  virtual void func(int i , int j)    
                    {
                        cout << "subClass  func(int i , int j)"<<i+j<<endl;
                    }
                 void func()
                     {
                         cout <<" void func()"<<endl;
                     }
    };
    
    
    
    void doPrint(parent *p)
    {
        p->func(1, 2); //实现多态特性
    }
    int main()
    {
        parent p;
        subClass s;
    
        p.func(1);//静态联编
        p.func(1,2);//静态联编
        p.func(1,2,3);//静态联编
        
    
        cout <<endl;
        s.func(4,5);//静态联编 编译时就知道了调用函数,最终会调用到,subClass 类中的 void func(int i , int j) 函数
    
    
        doPrint(&p);//展现动态联编
        doPrint(&s);//展现动态联编
    }
        

    运行结果:  

    func(int i )1
    parent  func(int i , int j)1,2
    parent  func(int i , int j,int k)1,2,k
    
    subClass  func(int i , int j)9
    parent  func(int i , int j)1,2
    subClass  func(int i , int j)3
  • 相关阅读:
    缓存穿透、缓存并发、缓存失效
    改善Java文档的理由、建议和技巧
    如何用消息系统避免分布式事务?
    灰度发布
    REFLECTION(反射)INTROSPECTION(内省、内观)
    常规版本如果新增字段或新增状态如何正确处理
    Git库管理规范
    .net 创建文件夹
    HTTP消息头
    C#读取指定文件夹中的所有文件
  • 原文地址:https://www.cnblogs.com/hjxzjp/p/11823275.html
Copyright © 2011-2022 走看看