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