虚函数:
虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:
vitual 函数返回值类型 虚函数名(形参表)
{ 函数体
}
虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型。以实现同一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。
当程序发现虚函数名前的关键字virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数。
动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式:
指向基类的指针变量名->虚函数名(实参表)
或 基类对象的引用名. 虚函数名(实参表)
虚函数的实例:
#include<iostream.h>
class Cshape
{ public: void SetColor( int color) { m_nColor=color;}
void virtual Display( void) { cout<<"Cshape"<<endl; }
private:
int m_nColor;
};
class Crectangle: public Cshape
{
public:
void virtual Display( void) { cout<<"Crectangle"<<endl; }
};
class Ctriangle: public Cshape
{
void virtual Display( void) { cout<<"Ctiangle"<<endl; }
};
class Cellipse :public Cshape
{
public: void virtual Display(void) { cout<<"Cellipse"<<endl;}
};
void main()
{
Cshape obshape;
Cellipse obEllipse;
Ctriangle obTriangle;
Csquare obSquare;
Cshape * pShape[4]=
{ &obShape, &obEllipse,&obTriangle, & obSquare };
for( int I= 0; I< 4; I++)
pShape[I].Display( );
}
本程序运行结果:
Cshape
Cellipse
Ctriangle
Csquare
所以,从以上程序分析,实现动态联编需要三个条件:
1、 必须把动态联编的行为定义为类的虚函数。
2、 类之间存在子类型关系,一般表现为一个类从另一个类公有派生而来。
3、 必须先使用基类指针指向子类型的对象,然后直接或者间接使用基类指针调用虚函数。
二、多继承中的虚函数
多继承中派生类是由多个基类派生的,在基类中存在虚函数,那么它的使用有什么不同的地方吗?
#include<iostream.h>
class Rectangle
{ public: virtual void display() { cout<<" Rectangle"<<endl; }
};
class Triangle
{ public: void display(){ cout<<"Triangle<<endl; }
};
class RecTriangle
{ public: void display( ){ cout<<"RecTriangle"<<endl; }
};
void main()
{ Rectangle a, *p1; //定义对象a,指针p1
Triangle b,*p2;
RecTriangel c;
P1=&a; //指针指向a
P1->display( ); //调用Rectangle::display( )
P2=&b; //指针指向b
P2->display( ); //调用Triangle::display( )
P1=&c; //基类指针指向c对象
P1->display( ); //调用RecTriangle::display( )
P2=&c;
P2->display();
}
虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:
vitual 函数返回值类型 虚函数名(形参表)
{ 函数体
}
虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型。以实现同一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。
当程序发现虚函数名前的关键字virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数。
动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式:
指向基类的指针变量名->虚函数名(实参表)
或 基类对象的引用名. 虚函数名(实参表)
虚函数的实例:
#include<iostream.h>
class Cshape
{ public: void SetColor( int color) { m_nColor=color;}
void virtual Display( void) { cout<<"Cshape"<<endl; }
private:
int m_nColor;
};
class Crectangle: public Cshape
{
public:
void virtual Display( void) { cout<<"Crectangle"<<endl; }
};
class Ctriangle: public Cshape
{
void virtual Display( void) { cout<<"Ctiangle"<<endl; }
};
class Cellipse :public Cshape
{
public: void virtual Display(void) { cout<<"Cellipse"<<endl;}
};
void main()
{
Cshape obshape;
Cellipse obEllipse;
Ctriangle obTriangle;
Csquare obSquare;
Cshape * pShape[4]=
{ &obShape, &obEllipse,&obTriangle, & obSquare };
for( int I= 0; I< 4; I++)
pShape[I].Display( );
}
本程序运行结果:
Cshape
Cellipse
Ctriangle
Csquare
所以,从以上程序分析,实现动态联编需要三个条件:
1、 必须把动态联编的行为定义为类的虚函数。
2、 类之间存在子类型关系,一般表现为一个类从另一个类公有派生而来。
3、 必须先使用基类指针指向子类型的对象,然后直接或者间接使用基类指针调用虚函数。
二、多继承中的虚函数
多继承中派生类是由多个基类派生的,在基类中存在虚函数,那么它的使用有什么不同的地方吗?
#include<iostream.h>
class Rectangle
{ public: virtual void display() { cout<<" Rectangle"<<endl; }
};
class Triangle
{ public: void display(){ cout<<"Triangle<<endl; }
};
class RecTriangle
{ public: void display( ){ cout<<"RecTriangle"<<endl; }
};
void main()
{ Rectangle a, *p1; //定义对象a,指针p1
Triangle b,*p2;
RecTriangel c;
P1=&a; //指针指向a
P1->display( ); //调用Rectangle::display( )
P2=&b; //指针指向b
P2->display( ); //调用Triangle::display( )
P1=&c; //基类指针指向c对象
P1->display( ); //调用RecTriangle::display( )
P2=&c;
P2->display();
}