最近突然发现,我对虚函数的理解有些迷茫,在网上查了查,做个个简要的理解。
一般,在C++中,虚函数是用来实现基类和派生类的成员函数的。看着貌似和重载函数相类似,但是两者确实还是有些区别。
首 先,虚函数是用virtual 来修饰这个函数的。一般这样的情况就是为我们声明了这个成员函数属于虚函数,于是我们就可以在其派生类中重新定义这个函数的实现方式,当程序在运行时动态的选择合适的成员函数(我个人认为,就是程序具体涉及到哪个类的时候,就调用该类中所定义的虚函数的实现方式。)。
其次,我觉得派生类中的虚函数无论是函数名,还是函数参数及参数类型都应该是一样的。这就是和重载函数最大的区别。
还有一种特点就是:如果子类继承了父类的一个函数(方法),而我们把父类的指针指向子类,则必须把父类的该函数(方法)设为virtual(虚函数)。
例如:
#include<iostream>
using namespace std;
class Cshape {
public:
void SetColor(int color){ m_nColor=color;}
virtual void Display( void){ cout<<"Cshape"<<endl; }
private:
int m_nColor;
};
class Crectangle: publicCshape {
public:
virtual void Display( void){ cout<<"Crectangle"<<endl; }
};
class Ctriangle: publicCshape {
virtual void Display( void){ cout<<"Ctriangle"<<endl; }
};
class Cellipse :publicCshape {
public:
virtual void Display(void){ cout<<"Cellipse"<<endl;}
};
void main()
{
Cshape obShape;
Cellipse obEllipse;
Ctriangle obTriangle;
Crectangle obRectangle;
Cshape * pShape[4]= {&obShape,&obEllipse,&obTriangle,& obRectangle };
for( int I= 0;I< 4; I++)
pShape[I]->Display( );
}
本程序运行结果:
Cshape
Cellipse
Ctriangle
Crectangle
如果把Cshape类里面 virtual void Display( void) 中的 virtual 去掉的话
运行结果就不一样了:
Cshape
Cshape
Cshape
Cshape
在 这里面的Cshape * pShape[4]= {&obShape,&obEllipse,&obTriangle,& obRectangle };这条语句就是把父类的指针指向了子类(我个人认为,如果不对,请指正),,然后再通过这个基类指针调用虚函数。于是在我们后来的调用display实 现时候,要把其定义为虚函数。
再一个,就是在调用虚函数的时候,也要注意一些其他的问题。1,虚函数的实现,一般主要涉及在基类和派生类之间。如果是两种无关的类的时候,就不存在什么虚函数的关联了。2,虚函数的一般先实现在用基类指针指向派生类对象的时候,然后间接或直接的使用基类指针调用虚函数(结合上个例子)。3,只有类的成员函数才可以为虚函数,而且构造函数是不能为虚函数的。但是,一个优秀的程序员总是喜欢把基类的析构函数作为虚函数来实现。一般说来这样的好处是,如果我们需要用delete删除一个派生类对象时,根据虚函数的特点,系统会调用与派生类相关的析构函数,而若若是不作为虚函数,那么直接就调用了基类的虚函数。4,虚函数只需要在声明的时候加上virtual,在其实现的时候,是不要的。且,一旦我们在基类中声明了虚函数后,其派生类中的同名函数自动为虚函数。最后个就是,在同一个派生类中,同一个虚函数只能声明和定义一次。