我们为什么要在C++中使用虚函数

类中的成员函数分为静态成员函数和非静态成员函数,而非静态成员函数又分为普通函数和虚函数。

至于为什么虚函数必须是非静态成员函数,可以看一下:http://blog.csdn.net/leiming32/article/details/8619893

我们在类中定义函数的时候,在前面加上virtual就可以声明为虚函数。

接下来我们看一个例子:

#include<iostream>
#include<string>
using namespace std;
class Student
{
	public:
		Student(string n,string nam,int sco);
		virtual void display();
	protected:
		string num;
		string name;
		int score;
};
Student::Student(string n,string nam,int sco)
{
	num=n;
	name=nam;
	score=sco;
}
void Student::display()
{
	cout<<"num:"<<num<<endl;
	cout<<"name:"<<name<<endl;
	cout<<"score:"<<score<<endl;
}
class Graduate:public Student
{
	public:
		Graduate(string n,string nam,int sco,string un);
		virtual void display();
	private:
		string university;
};
Graduate::Graduate(string n,string nam,int sco,string un):Student(n,nam,sco),university(un){};
void Graduate::display()
{
	cout<<"num:"<<num<<endl;
	cout<<"name:"<<name<<endl;
	cout<<"score:"<<score<<endl;
	cout<<"university:"<<university<<endl;
}
int main()
{
	Student *p;
	p=new Student("001","QianShou",100);
	p->display();
	cout<<"==============没有节操的分割线================"<<endl;
	p=new Graduate("001","QianShou",100,"SDNU");
	p->display();
	return 0;
}


运行结果:

/*
	num:001
	name:QianShou
	score:100
	==============没有节操的分割线================
	num:001
	name:QianShou
	score:100
	university:SDNU
*/


p是基类指针,当它指向基类的对象时,调用的display函数为基类中的成员函数,当它指向派生类的对象时,调用的display函数为派生类中的成员函数。

这就难免出现一个问题,我们为什么要用指向基类的指针指向派生类,然后再通过指针调用派生类中的成员函数呢?

为什么不直接建立一个指向派生类的指针,然后调用成员函数呢?这样都没有必要在基类中声明虚函数了。

我们考虑这样一个问题,如果我们要去一个城市的好多不同的地方,如果我们乘坐公交车的话,每去一个地方就需要选择不同的公交车;而如果我们乘坐出租车的话,我们只需要找一个出租车,然后不断告诉它不同的地点,它就能够带我们去不同的地方。

道理是相似的:

乘坐公交车:

假如一个基类有20个派生类,当我们分别访问这21个派生类和基类的时候,我们就需要为每一个类建立一个指针,然后通过不同的指针去访问不同的类的对象,就好像我们通过乘坐不同的公交车到达不同的地点一样。

乘坐出租车:

如果我们在基类中建立相应的虚函数,我们就只需要建立一个指向基类的指针。当我们需要访问该基类或者它的20个派生类的时候,我们只需将相应的类的地址赋给指向基类的指针,即可访问该派生类中的虚函数。就像我们在做出租车的时候,不断告诉司机我们的下一个地址一样。


posted @ 2013-12-08 17:25  千手宇智波  阅读(719)  评论(0编辑  收藏  举报