您的位置:首页 > 编程语言 > C语言/C++

什么是C++虚函数、虚函数的作用和使用方法

2019-04-12 10:34 309 查看

什么是C++虚函数、虚函数的作用和使用方法

我们知道,在同一类中是不能定义两个名字相同、参数个数和类型都相同的函数的,否则就是“重复定义”。但是在类的继承层次结构中,在不同的层次中可以出现名字相同、参数个数和类型都相同而功能不同的函数。

能否用同一个调用形式,既能调用派生类又能调用基类的同名函数。在程序中不是通过不同的对象名去调用不同派生层次中的同名函数,而是通过指针调用它们。例如,用同一个语句“pt->display( );”可以调用不同派生层次中的display函数,只需在调用前给指针变量 pt 赋以不同的值(使之指向不同的类对象)即可。

打个比方,你要去某一地方办事,如果乘坐公交车,必须事先确定目的地,然后乘坐能够到达目的地的公交车线路。如果改为乘出租车,就简单多了,不必查行车路线,因为出租车什么地方都能去,只要在上车后临时告诉司机要到哪里即可。如果想访问多个目的地,只要在到达一个目的地后再告诉司机下一个目的地即可,显然,“打的”要比乘公交车 方便。无论到什么地方去都可以乘同—辆出租车。这就是通过同一种形式能达到不同目的的例子。

C++中的虚函数就是用来解决这个问题的。虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。

(1)在基类用virtual声明成员函数为虚函数。这样就可以在派生类中重新定义此函数,为它赋予新的功能,并能方便被调用。
在类外定义虚函数时,不必在定义virtual

(2)在派生类中重新定义此函数,要求函数名,函数类型,函数参数个数和类型全部与基类的虚函数相同,并根据派生类的需要重新定义函数体。

c++规定,当一个成员函数被声明为虚函数后,其派生类的同名函数都自动成为虚函数。因此在派生类重新声明该

虚函数时,可以加virtual,也可以不加,但习惯上一般在每层声明该函数时都加上virtual,使程序更加清晰。

如果再派生类中没有对基类的虚函数重新定义,则派生类简单的继承起基类的虚函数。

(3)定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。
(4)通过该指针变量调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。

#include<iostream>
#include<string>

using namespace std;

class Student
{
public:
Student(int , string, float);
void display();
protected:
int num;
string name;
float score;
};
Student::Student(int n, string na, float s)
{
num=n;
name=na;
score=s;
}
void Student::display()
{
cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<endl;
}
class Graduate:public Student
{
public:
Graduate(int , string , float, float);
void display();

private:
float pay;

};
Graduate::Graduate(int n, string na, float s, float p):Student(n,na,s),pay(p)
{
}
void Graduate::display()
{
cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\npay:"<<pay<<endl;
}

int main()
{
Student stud1(110,"SDL",99.8);
Graduate grad1(120,"CCT",88.9, 250.5);

Student *p;

p=&stud1;
cout<<"student:"<<endl;
p->display();
p=&grad1;
cout<<"graduate:"<<endl;
p->display();

return 0;
}

输出结果为:

此时没有将任何函数声明为虚函数,所以在Graduate类中diaplay()函数输出时没有pay的值,以为p指针是Student类的,本身Student不包括pay数据。

但如果我们想输出pay的值,只要把Student类中的display函数声明为虚函数即可,只要把它改为virtual void display()声明为虚函数就行,输出的结果为:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: