虚函数实现多态:
多态:相同的调用语句,具有不同的表现形式(不同的执行结果)。多态由继承而来,由虚函数virtual来实现。
多态(Polymorphism): 我们以相同的指令却唤起了不同的函数,这种性质称为Polymorphism,意思是"theability to assume many forms"(多态)。
编译器无法在编译时期判断pEmp->computePay 到底是调用哪一个函数,必须在执行时期才能评估之,这称为后期绑定late binding 或动态绑定dynamic binding。
至于 C 函数或 C++ 的non-virtual 函数,在编译时期就转换为一个固定地址的调用了,这称为前期绑定early binding 或静态绑定static binding。
class Father { public: virtual void func(){cout << "调用father的func" << endl;} }; class Son : public Father { public: void func(){cout << "调用Son的func" << endl;} }; int main() { Son son; Father *ptrFuther = &son; ptrFuther->func(); //若Father类中的func函数有virtual修饰,结果为:"调用Son的func" return 0; //若Father类中的func函数没有virtual修饰,结果为:"调用father的func" }
虚函数的调用:
/*---------------------------------
三种调用虚函数的方式比较:
当函数的形参为对象、指针、引用,调用virtual函数时,
则指针和引用会有多态,对象无多态。
---------------------------------*/
class father
{
public:
virtual void run()const
{cout<<"父亲可以跑一万米"<<endl;}
};
class son :public father
{
public:
void run()const
{cout<<"儿子可以跑十万米"<<endl;}
};
void A(father); //形参为father类的对象
void B(father*); //形参为father类的指针
void C(father&); //形参为father类的引用
int main()
{
father *p=0;
p = new son;
A(*p); //将不会呈现出多态性,因为函数A()是对象调用
B(p);
C(*p);
return 0;
}
void A(father A) //形参为father类的对象
{ //由于是用对象的方式来调用虚函数,那就不会有多态作用
A.run(); //那么派生类赋给基类对象,将不会调用派生类的同名函数
}
void B(father* B) //形参为father类的指针
{
B->run();
}
void C(father& C) //形参为father类的引用
{
C.run();
}
/*
结果:
父亲可以跑一万米
儿子可以跑十万米
儿子可以跑十万米
*/
son s;
father *p = &s; //指针形式 - 多态
p->run(); //"儿子可以跑十万米"
father &p1 = s; //引用形式 - 多态
p1.run(); //"儿子可以跑十万米"
father p2 = s; //对象形式 - 无多态
p2.run(); //"父亲可以跑一万米"