虚函数是在基类中冠以关键字virtual的成员函数。它提供了一种接口界面,当从父类中继承的时候,虚函数和被继承的函数具有相同的签名。但是在运行过程中,运行系统将根据对象的类型,自动地选择适当的具体实现运行。虚函数是面向对象编程实现多态的基本手段。虚函数可以在一个或多个派生类中被重定义。先看下一下的例子:
#include <iostream>
using namespace std;
class A
{
public:
void who(){cout<<"base\n";}
};
class first_d:public A
{
public:
void who(){cout<<"first derivation\n";}
};
class second_d:public A
{
public:
void who(){cout<<"senond derivation\n";}
};
void main()
{
A a;A *p;
first_d fd;second_d sd;//定义对象
p=&a;//基类指针指向基类对象
p->who();
p=&fd;//基类指针指针指向派生类对象
p->who();
p=&sd;
p->who();
fd.who();
sd.who();
}
从运行的结果可以看出,基类指针p,当其指向的是派生类的对象时p->who()调用的都是基类定义的who。为调用不同版本的函数,需要显式使用对象:fd.who()和sd.who()才能够调用派生类对象中的函数。
这是因为通过指针引起的普通函数调用,仅与指针(或者引用)的类型有关,而与此刻正指向的对象无关。若想随着指针p所指的对象不同而调用不同版本的who函数,就实现了运行时的多态性。这种机制的实现依赖于在基类中把成员函数who()说明为虚函数。
对程序进行修改,修改结果也就是将基类中的who函数前面加个virtual关键字而已:
#include <iostream>
using namespace std;
class A
{
public:
virtual void who(){cout<<"base\n";}//将who函数说明为虚函数
};
class first_d:public A
{
public:
void who(){cout<<"first derivation\n";}
};
class second_d:public A
{
public:
void who(){cout<<"senond derivation\n";}
};
void main()
{
A a;A *p;
first_d fd;second_d sd;//定义对象
p=&a;//基类指针指向基类对象
p->who();
p=&fd;//基类指针指针指向派生类对象
p->who();
p=&sd;
p->who();
fd.who();
sd.who();
}
从运行的结果是可以看出,随着指针指向不同的对象,实现了多个版本的who函数的访问。
以下再举个例子:
#include <iostream>
using namespace std;
class figure
{
protected:
double x,y;
public:
void set_dim(double i,double j=0){x=i;y=j;}
virtual void show_area()
{cout<<"no area computation defined for this class\n";}
};
class triangle:public figure
{
public:
void show_area()
{
cout<<" triangle with high "<<x<<" and base "<<y;
cout<<" has an area of "<<x*0.5*y<<"\n";
}
};
class square:public figure
{
public:
void show_area()
{
cout<<" square with dimention "<<x<<"*"<<y;
cout<<" has an area of "<<x*y<<"\n" ;
}
};
class circle:public figure
{
public:
void show_area()
{
cout<<" circle with radius "<<x;
cout<<" has an area of "<<3.14*x*x<<"\n";
}
};
void main()
{
figure *p;triangle t;square s;circle c;
p=&t;
p->set_dim(10,5);p->show_area();
p=&s;
p->set_dim(10,5);p->show_area();
p=&c;
p->set_dim(10);p->show_area();
}
可以通过虚函数实现多态性,一个指针指向不同的对象,调用不同的函数。