天天看点

C++虚函数(多态性)

C++的多态性用一句话可以概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,在运行时将会根据对象的实际情况类型来调用相应的函数。

C++的多态性是在程序运行时,依据对象的类型来确认调用哪一个函数,这就是迟绑定。

上代码:

#include <iostream.h>

class animal

{

     public:

                  void breath()  //C++中需要添加virtual关键字才可以实现多态

                   {

                   cout << "animal breath"<< endl;

                   }

                  void sleep(){

                         cout<< "animal sleep"<<endl;

            }

};

class fish:public animal

{

   public:

   void breath()

    {

        cout << "fish bubble"<endl;

      }

};

void fn(animal *pAn)

   {

    pAn->breath();

}

void  main()

{

     animal *pAn;

    fish fh;

     pAn = &fh;

    fh(pAn);

}

运行结果:animal breath;

出现这种现象的原因是因为fish对象也是一个animal对象,将fish类型转换成animal类型不用强制类型转换,C++编译器会自动进行这种转换。若要调用fish的breath函数,需要在基类的函数前面加上virtual关键字,C++编译器就会采用迟绑定技术,在程序运行时,依据对象类型确定调用哪个函数。

在Java里面,不用添加virtual关键字,也可以实现多态性。java的普通成员函数(没有被static、native等关键字修饰)就是虚函数,原因很简单,它本身就实现虚函数实现的功能------多态。在Java里通过函数重写就可以实现多态性。

顺便在谈一下C++的隐藏与覆盖。

隐藏有两种情况:

(1)派生类的函数与基类的函数完全相同(函数名和形参列表),只是基类的函数函数没有使用virtual关键字。此时基类的函数将被隐藏。

(2)派生类的函数与基类的函数同名,但参数列表不同,这种情况下,不管基类函数声明是否有virtual关键字,基类的函数都将被隐藏。

覆盖:

(1)基类函数必须是虚函数。(使用virtual关键字声明)

(2)发生覆盖的两个函数分别位于派生类和基类中。

(3)函数名与参数列表必须完全相同。

C++的多态性是通过虚函数来实现的,所以函数的覆盖总是和多态性关联在一起。在函数覆盖的情况下,编译器会在运行时根据对象的实际类型来确定要调用的函数。