C++知识学习--虚函数介绍和使用
[ 回目录 ]1 虚函数介绍
被virtual关键字修饰的成员函数,就是虚函数,虚函数可以分为一般虚函数和纯虚函数
纯虚函数在基类中没有定义,其子类务必实现此函数。虚函数的作用主要实现了多态,在函数运行中,根据对象的不同调用相应的函数。
[ 回目录 ]2 虚函数使用介绍
有如下一段代码,CBase为虚基类,包括一般函数f,虚函数vf,纯虚函数pvf;DeriveA类和DeriveB继承与CBase,DeriveA实现了pvf,DeriveB实现了f, vf,和pvf
class CBase
{
public:
CBase(){}
virtual ~CBase(){}
void f( void );
virtual void vf( void );
virtual void pvf( void ) = 0;
};
void CBase::f()
{
std::cout << "CBase::"<<__FUNCTION__ << std::endl;
}
void CBase::vf()
{
std::cout << "CBase::"<<__FUNCTION__ << std::endl;
}
class DeriveA : public CBase
{
public:
DeriveA(){}
~DeriveA(){}
void pvf(void);
};
void DeriveA::pvf( void )
{
std::cout << "DeriveA::" << __FUNCTION__ << std::endl;
}
class DeriveB : public CBase
{
public:
DeriveB(){}
~DeriveB(){}
void f(void);
void vf(void);
void pvf(void);
};
void DeriveB::f()
{
std::cout << "DeriveB::"<< __FUNCTION__<< std::endl;
}
void DeriveB::vf()
{
std::cout << "DeriveB::"<<__FUNCTION__ << std::endl;
}
void DeriveB::pvf()
{
std::cout << "DeriveB::"<<__FUNCTION__ << std::endl;
}
int main()
{
CBase* pObjectA = (CBase*)new DeriveA();
CBase* pObjectB = (CBase*)new DeriveB();
pObjectA->f();
pObjectA->vf();
pObjectA->pvf();
pObjectB->f();
pObjectB->vf();
pObjectB->pvf();
}
主函数定义了两个CBase的对象指针,并分别被复制为DeriveA和DeriveB,调用三个函数后可以结果如下
CBase::CBase::f
CBase::CBase::vf
DeriveA::DeriveA::pvf
CBase::CBase::f
DeriveB::DeriveB::vf
DeriveB::DeriveB::pvf
请按任意键继续. . .
结果说明:
对于普通函数,无论派生类是否重新定义了基类的函数,都只会调用基类的函数
对于虚函数,如果派生类没有重新重载此函数,则调用基类的函数,如果重载了,则调用派生类的函数
对于纯虚函数,派生类必须重载此函数,所以调用派生类的函数
[ 回目录 ]3 虚函数的实现说明
虚函数是通过虚函数表来实现的vtbl,用一个指针vptr指向vtbl
Vtbl(CBase):
CBase::f
CBase::vf
CBase::pvf
Vtbl(DeriveA)
CBase::f
CBase::vf
DeriveA::pvf
Vtbl(DeriveB)
CBase::f
DeriveB::vf
DeriveB::pvf
派生类的vtbl中把基类的函数放在vtbl的最前面,当函数为虚函数时,就会覆盖基类函数。
在运行过程中根据vptr调用相应的函数。