一 C++虚拟函数(C++ virtual function)杂谈
我们在编程的时候,经常会遇到这样的情况,假设有两个对象,你要在函数中分别调用它们的OnDraw方法,我们以前的做法一般是这样的。
void f(int iType)
{
switch(iType)
{
case 1:
//CCircle OnDraw
break;
case 2:
//CRectangle OnDraw
break;
}
}
这种方法当然能解决我们的问题,但是如果有新的类型要增加,它就必须要往下加代码才行了,这样函数里的代码会越写越长。你可能会想我的类型不多,往下加也不会太长,但是这种想法是不可取的,因为实际工作当中,我们经常遇到的情况是,一个系统可能要维护好几年,甚至10几年都会有,所以不可预知的事情很多,做设计的时候不能有这种侥幸心里。C++中提供了虚函数,可以方便我们解决这个问题。
class CShape
{
public:
virtual void OnDraw(){}
};
class CCircle:public CShape
{
public:
void OnDraw()
{
cout<<"CCircle OnDraw"<<endl;
}
};
class CRectangle: public CShape
{
void OnDraw()
{
cout<<"CRectangle OnDraw"<<endl;
}
};
定义一个接口函数,把基类作为型参,对象传入后就可以调用到对应的函数了。
void SelfDraw(CShape *_shap)
{
_shap->OnDraw();
}
在调用的时候只需要写类似如下的代码。
CCircle c1;
CRectangle r1;
SelfDraw(&c1);
SelfDraw(&r1);
程序编译运行后的结果如下。
可能刚学c++不久的朋友不知道为什么可以这样使用,为什么基类可以正确的调用到子类的函数,那么让我们来看看秘密到底在哪里吧。
秘密就是__vfptr(virtual function pointer),__vfptr是一个指针数组指向虚函数,当CCircle对象传入基类指针后,虚函数指针会指向CCircle重载的OnDraw函数,所以我们就会看到SelfDraw中_shap->OnDraw()可以正确调用到它对应子类函数了。