当前位置 主页 > 网站技术 > 代码类 >

    C++之多态(内容不错)

    栏目:代码类 时间:2020-01-31 06:08

    编译环境:WIN10 VS2017

    这篇博客有点长,但都是满满的干货,一定要看到最后,那才是重点。

    什么是多态?

    顾名思义就是同一个事物在不同场景下的多种形态。

    这里写图片描述 

    下面会具体的详细的介绍。

    静态多态

    我们以前说过的函数重载就是一个简单的静态多态

    int Add(int left, int right)
    {
     return left + right;
    }
    double Add(double left, int right)
    {
     return left + right;
    }
    
    int main()
    {
     Add(10, 20);
     //Add(10.0, 20.0); //这是一个问题代码
     Add(10.0,20); //正常代码
     return 0;
    }

    这里写图片描述 

    可以看出来,静态多态是编译器在编译期间完成的,编译器会根据实参类型来选择调用合适的函数,如果有合适的函数可以调用就调,没有的话就会发出警告或者报错。。。比较简单,不做多介绍。

    这里写图片描述

    动态多态

    什么是动态多态呢?
    动态多态: 显然这和静态多态是一组反义词,它是在程序运行时根据基类的引用(指针)指向的对象来确定自己具体该调用哪一个类的虚函数。

    我在西安临潼上学,我就以这边的公交车举个栗子啊:

    class TakeBus
    {
    public:
     void TakeBusToSubway()
     {
      cout << "go to Subway--->please take bus of 318" << endl;
     }
     void TakeBusToStation()
     {
      cout << "go to Station--->pelase Take Bus of 306 or 915" << endl;
     }
    };
    //知道了去哪要做什么车可不行,我们还得知道有没有这个车
    class Bus
    {
    public:
     virtual void TakeBusToSomewhere(TakeBus& tb) = 0; //???为什么要等于0
    };
    
    class Subway:public Bus
    {
    public:
     virtual void TakeBusToSomewhere(TakeBus& tb)
     {
      tb.TakeBusToSubway();
     }
    };
    class Station :public Bus
    {
    public:
     virtual void TakeBusToSomewhere(TakeBus& tb)
     {
      tb.TakeBusToStation();
     }
    };
    
    int main()
    {
     TakeBus tb;
     Bus* b = NULL;
     //假设有十辆公交车,如果是奇数就是去地铁口的,反之就是去火车站的
     for (int i = 1; i <= 10; ++i)
     {
      if ((rand() % i) & 1)
       b = new Subway;
      else
       b = new Station;
     }
     b->TakeBusToSomewhere(tb);
     delete b;
     return 0;
    }

    这就是一个简单的动态多态的例子,它是在程序运行时根据条件去选择调用哪一个函数。
    而且,从上面的例子我们还发现了我在每一个函数前都加了virtual这个虚拟关键字,想想为什么?如果不加会不会构成多态呢?
    干想不如上机实践:

    class Base
    {
    public:
     virtual void Funtest1(int i)
     {
      cout << "Base::Funtest1()" << endl;
     }
     void Funtest2(int i)
     {
      cout << "Base::Funtest2()" << endl;
     }
    };
    class Drived :public Base
    {
     virtual void Funtest1(int i)
     {
      cout << "Drived::Fubtest1()" << endl;
     }
     virtual void Funtest2(int i)
     {
      cout << "Drived::Fubtest2()" << endl;
     }
     void Funtest2(int i)
     {
      cout << "Drived::Fubtest2()" << endl;
     }
    };
    void TestVirtual(Base& b)
    {
     b.Funtest1(1);
     b.Funtest2(2);
    }
    int main()
    {
     Base b;
     Drived d;
     TestVirtual(b);
     TestVirtual(d);
     return 0;
    }