虚函数在C++上应用
2017-04-05 17:45
211 查看
浅谈C++中的虚函数
虚函数的作用
在类的继承层次结构中,在不同的层次中可以出现名字相同、参数个数和类型都相同而
功能不同的函数。编译系统按照同名覆盖的原则决定调用的对象。
C++中的虚函数就是用来解决这个问题的。虚函数的作用是允许在派生类中重新定义与
基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。
//在下面的程序中Student 是基类,Graduate 是派生类,它们都有display 这个同名的函数。
#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 *pt=&stud1; //定义指向基类对象的指针变量pt
pt->display( );
pt=&grad1;
pt->display( );
return 0;
}
运行结果:
num:1001
name:Li
score:87.5
num:2001
name:Wang
score:98.5
从结果可以知道,它们执行的都是基类的display。
下面我们来对程序作一点修改,在Student类中声明display函数时,在最左面加一个关
键字virtual,即virtual void display( );这样就把Student类的display函数声明为虚函
数。程序其他部分都不改动。
运行结果:
num:1001 (stud1的数据)
name:Li
score:87.5
num:2001 (grad1中基类部分的数据)
name:Wang
score:98.5
pay=563.5 (这一项以前是没有的)
由虚函数实现的动态多态性就是: 同一类族中不同类的对象,对同一函数调用作出不同
的响应。虚函数的使用方法是:
(1) 在基类用virtual声明成员函数为虚函数。这样就可以在派生类中重新定义此函数,
为它赋予新的功能,并能方便地被调用。在类外定义虚函数时,不必再加virtual。
(2) 在派生类中重新定义此函数,要求函数名、函数类型、函数参数个数和类型全部与基
类的虚函数相同,并根据派生类的需要重新定义函数体。
C++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚
函数。因此在派生类重新声明该虚函数时,可以加virtual,也可以不加,但习惯上一般在
每一层声明该函数时都加virtual,使程序更加清晰。
如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函
数。
(3) 定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。
(4) 通过该指针变量调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。
通过虚函数与指向基类对象的指针变量的配合使用,就能方便地调用同一类族中不同
类的同名函数,只要先用基类指针指向即可。如果指针不断地指向同一类族中不同类的对象,
就能不断地调用这些对象中的同名函数。
需要说明;有时在基类中定义的非虚函数会在派生类中被重新定义(如例6.1中的Area
函数),如果用基类指针调用该成员函数,则系统会调用对象中基类部分的成员函数;如果
用派生类指针调用该成员函数,则系统会调用派生类对象中的成员函数,这并不是多态性行
为(使用的是不同类型的指针),没有用到虚函数的功能。
以前介绍的函数重载处理的是同一层次上的同名函数问题,而虚函数处理的是不同派生
层次上的同名函数问题,前者是横向重载,后者可以理解为纵向重载。但与重载不同的是: 同
一类族的虚函数的首部是相同的,而函数重载时函数的首部是不同的(参数个数或类型不
同)。
虚函数的作用
在类的继承层次结构中,在不同的层次中可以出现名字相同、参数个数和类型都相同而
功能不同的函数。编译系统按照同名覆盖的原则决定调用的对象。
C++中的虚函数就是用来解决这个问题的。虚函数的作用是允许在派生类中重新定义与
基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。
//在下面的程序中Student 是基类,Graduate 是派生类,它们都有display 这个同名的函数。
#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 *pt=&stud1; //定义指向基类对象的指针变量pt
pt->display( );
pt=&grad1;
pt->display( );
return 0;
}
运行结果:
num:1001
name:Li
score:87.5
num:2001
name:Wang
score:98.5
从结果可以知道,它们执行的都是基类的display。
下面我们来对程序作一点修改,在Student类中声明display函数时,在最左面加一个关
键字virtual,即virtual void display( );这样就把Student类的display函数声明为虚函
数。程序其他部分都不改动。
运行结果:
num:1001 (stud1的数据)
name:Li
score:87.5
num:2001 (grad1中基类部分的数据)
name:Wang
score:98.5
pay=563.5 (这一项以前是没有的)
由虚函数实现的动态多态性就是: 同一类族中不同类的对象,对同一函数调用作出不同
的响应。虚函数的使用方法是:
(1) 在基类用virtual声明成员函数为虚函数。这样就可以在派生类中重新定义此函数,
为它赋予新的功能,并能方便地被调用。在类外定义虚函数时,不必再加virtual。
(2) 在派生类中重新定义此函数,要求函数名、函数类型、函数参数个数和类型全部与基
类的虚函数相同,并根据派生类的需要重新定义函数体。
C++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚
函数。因此在派生类重新声明该虚函数时,可以加virtual,也可以不加,但习惯上一般在
每一层声明该函数时都加virtual,使程序更加清晰。
如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函
数。
(3) 定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。
(4) 通过该指针变量调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。
通过虚函数与指向基类对象的指针变量的配合使用,就能方便地调用同一类族中不同
类的同名函数,只要先用基类指针指向即可。如果指针不断地指向同一类族中不同类的对象,
就能不断地调用这些对象中的同名函数。
需要说明;有时在基类中定义的非虚函数会在派生类中被重新定义(如例6.1中的Area
函数),如果用基类指针调用该成员函数,则系统会调用对象中基类部分的成员函数;如果
用派生类指针调用该成员函数,则系统会调用派生类对象中的成员函数,这并不是多态性行
为(使用的是不同类型的指针),没有用到虚函数的功能。
以前介绍的函数重载处理的是同一层次上的同名函数问题,而虚函数处理的是不同派生
层次上的同名函数问题,前者是横向重载,后者可以理解为纵向重载。但与重载不同的是: 同
一类族的虚函数的首部是相同的,而函数重载时函数的首部是不同的(参数个数或类型不
同)。
相关文章推荐
- C++成员函数指针的应用(学习收录)
- 关于C++中函数参数是省略号的应用
- C++中的函数多态性应用&虚函数的灵活应用
- 详解C++中的纯虚函数(虚函数区别)&多态性以及实例应用
- C/C++ 可变参数函数的原理和应用
- C++成员函数指针的应用
- visual c++ 6.0创建一个c++工程+外部函数应用举例
- C++调用C文件函数简单应用
- C++成员函数指针的应用
- C++ inline函数正确应用方法介绍
- c++中虚函数的简单应用
- C++ 可变形参函数的应用
- [C++] 函数指针的应用
- c++复习八 函数递归小应用
- 对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
- C++的va_start() va_end()函数应用(转)
- C++的va_start() va_end()函数应用(转)
- C++成员函数指针的应用(转)
- 哈希查找的应用之打印c++源文件中关键字和函数名
- 从零开始学C++之STL(九):函数适配器bind2nd 、mem_fun_ref 源码分析、函数适配器应用举例