C++虚函数的作用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

前言

参考:http://c.biancheng.net/cpp/biancheng/view/244.html
简化版便于快速理解

提示:以下是本篇文章正文内容,下面案例可供参考

一、虚函数是什么?

虚函数,是指被virtual关键字修饰的成员函数。

虚函数,是可继承且可重写的函数

通常所说的虚函数实现的多态与虚函数作用相关:通过一个基类指针指向各个派生类,无需再定义指向派生类的指针,便于访问其成员函数。

二、代码对比

1.无虚函数

代码如下(示例):

#include <iostream>
#include <string>
using namespace std;
//声明基类Student
class Student
{
public:
   Student(int, string,float);  //声明构造函数
   void display( );//声明输出函数
protected:  //受保护成员,派生类可以访问
   int num;
   string name;
   float score;
};
//Student类成员函数的实现
Student::Student(int n, string nam,float s)//定义构造函数
{
   num=n;
   name=nam;
   score=s;
}
void Student::display( )//定义输出函数
{
   cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\n\n";
}
//声明公用派生类Graduate
class Graduate:public Student
{
public:
   Graduate(int, string, float, float);//声明构造函数
   void display( );//声明输出函数
private:float pay;
};
// Graduate类成员函数的实现
void Graduate::display( )//定义输出函数
{
   cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\npay="<<pay<<endl;
}
Graduate::Graduate(int n, string nam,float s,float p):Student(n,nam,s),pay(p){}
//主函数
int main()
{
   Student stud1(1001,"Li",87.5);//定义Student类对象stud1
   Graduate grad1(2001,"Wang",98.5,563.5);//定义Graduate类对象grad1
   Student *pt1=&stud1;//定义指向基类对象的指针变量pt
   pt1->display( );
   Graduate *pt2=&grad1;
   pt2->display( );
   return 0;
}

2.有虚函数

在students类声明display前加上关键字virtual

同时将

   Student *pt1=&stud1;//定义指向基类对象的指针变量pt1
   pt1->display( );
   Graduate *pt2=&grad1;//指向Grad指针pt2
   pt2->display( ); 

修改为

   Student *pt = &stud1;//定义指向基类对象的指针变量pt
   pt->display( );
   pt=&grad1;
   pt->display( );
   return 0;

此时,会发现一个pt指针输出了stud1和grad1的全部数据。

代码如下(示例):

#include <iostream>
#include <string>
using namespace std;
//声明基类Student
class Student
{
public:
   Student(int, string,float);  //声明构造函数
   virtual void display( );//声明输出函数
protected:  //受保护成员,派生类可以访问
   int num;
   string name;
   float score;
};
//Student类成员函数的实现
Student::Student(int n, string nam,float s)//定义构造函数
{
   num=n;
   name=nam;
   score=s;
}
void Student::display( )//定义输出函数
{
   cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\n\n";
}
//声明公用派生类Graduate
class Graduate:public Student
{
public:
   Graduate(int, string, float, float);//声明构造函数
   void display( );//声明输出函数
private:float pay;
};
// Graduate类成员函数的实现
void Graduate::display( )//定义输出函数
{
   cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\npay="<<pay<<endl;
}
Graduate::Graduate(int n, string nam,float s,float p):Student(n,nam,s),pay(p){}
//主函数
int main()
{
   Student stud1(1001,"Li",87.5);//定义Student类对象stud1
   Graduate grad1(2001,"Wang",98.5,563.5);//定义Graduate类对象grad1
   Student *pt = &stud1;//定义指向基类对象的指针变量pt
   pt->display( );
   pt=&grad1;
   pt->display( );
   return 0;
}

上述需要说明的是,基类指针是指向基类对象,如果用它指向派生类对象,则进行指针类型转换,将派生类对象的指针先转换为基类的指针,所以基类指针指向的是派生类对象中的基类部分。

在程序修改前,是无法通过基类指针去调用派生类对象中的成员函数的。引入虚函数后,在派生类的基类部分中,派生类的虚函数取代了基类原来的虚函数,因此在使基类指针指向派生类对象后,调用虚函数时就调用了派生类的虚函数。

三、总结

虚函数虚在“推迟联编”或者“动态联编”上,即一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值