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
原文地址:https://www.cnblogs.com/hjxzjp/p/11823275.html