虚函数常用于继承,展现了多态性
理解
多态性:名字相同的两个函数,但有多种用途。重载就是多态的一种简单形式。
虚函数:在基类中声明的函数,派生类赋值给基类调用函数时会被覆盖。
虚函数的定义
示例
#include<iostream>
using namespace std ;
class Base
{ public : Base(char xx) { x = xx; }
virtual void who() { cout << "Base class: " << x << "\n" ; }
protected: char x;
} ;
class First_d : public Base
{ public : First_d(char xx, char yy):Base(xx) { y = yy; }
void who() { cout << "First derived class: "<< x << ", " << y << "\n" ; }
protected: char y;
} ;
class Second_d : public First_d
{ public :
Second_d( char xx, char yy, char zz ) : First_d( xx, yy ) { z = zz; }
void who() { cout<<"Second derived class: "<<x<<", "<<y<<", "<<z<<"\n" ; }
protected: char z;
} ;
int main()
{ Base B_obj( 'A' ) ; First_d F_obj( 'T', 'O' ) ; Second_d S_obj( 'E', 'N', 'D' ) ;
Base * p ;
p = & B_obj ; p -> who() ;
p = &F_obj ; p -> who() ;
p = &S_obj ; p -> who() ;//一般指针调用。体现多态
}
这时候会调用各自的who()函数,显示分别为A,TO,END。
注意:
1.虚函数必须是类的成员函数在基类定义,需要派生类公有继承。
2.不能将友元说明为虚函数,但虚函数可以是另一个类的友元
3.析构函数可以是虚函数,但构造函数不能是虚函数
4.在派生类中重载基类的虚函数要求函数名、返回类型、参数个数、参数类型和顺序完全相同。(仅返回值不同会报错)
5.构造函数,静态成员函数,内联成员函数不能是虚函数。析构函数可以是虚的,并且通常是虚函数。(虚析构函数为了正确引导析构地址)
一个有趣的小程序(有助于理解)
#include <iostream.h> class A { public: virtual double funA(double x) { cout<<"funA of class A called."<<endl; return x*x; } double funB(double x) { return funA(x)/2; } }; class B:public A { public: virtual double funA(double x) { cout<<"funA of class B called."<<endl; return 2*x*x; } }; class C:public B { public: virtual double funA(double x) { cout<<"funA of class C called."<<endl; return 3*x*x; } }; void main() { C objc; cout<<objc.funB(3)<<endl; B objb; cout<<objb.funB(3)<<endl; }
这时候C的funA会得到13.5,B的funA会得到9(可以体会体会)
纯虚函数
一般来说纯虚函数是在基类无法给出有意义的实现的时候声明为纯虚函数。
简单地说就是只声明,不定义功能。
功能留给派生类,体现多态性。
声明形式:
virtual 类型 函数名(参数表)= 0 ; //这个等于零很灵性。
具有纯虚函数的类成为抽象类。
纯虚函数具体实例可以参考一些登陆系统,登陆系统输入不同类型的账号密码,可以进入不同的界面,管理员界面或者用户界面,通过一个公有的登陆,来登陆两个不同界面。