虚拟函数-4、纯虚拟函数

在示例2.3中,基类CCustEdit定义了虚拟函数BuildValues()为子类提供重载的形式,而这个虚拟函数本身从来就没有执行过,也没有执行的必要。并且,由基类CCustEdit实例化的对象也没有什么应用价值。CCustEdit类白白浪费了资源。对于这种情况,可以将基类的虚拟函数定义为纯虚函数。

纯虚拟函数没有函数体,专为派生类提供重载的形式。只要形象地将虚拟函数赋值为0,即定义了纯虚函数。例如:

void virtual BuildValues(char * Statement)=0;

定义了纯虚函数的类称为抽象基类。抽象基类节省了内存空间,但不能用来实例化对象。其派生类必须重载所有的纯虚函数,否则产生编译错误。

纯虚函数和常规虚函数可以同时出现在一个类中,即抽象基类中也可以定义常规虚函数。示例2.5是对示例2.4的改写,其中基类Ca已定义为抽象基类。此基类包含一个纯虚函数OutputTitle()和一个常规虚函数OutputStyle(),以及一个虚析构函数。

示例清单2.5

#include "stdio.h"

#include "string.h"

class Ca

{

public:

         Ca(){m_Style=0;}

         Ca(int style){m_Style=style;}

//虚析构函数

         virtual ~Ca(){ printf(“~ca() called\n”);}

//常规虚函数

         virtual void OutputStyle()

         {

          printf("%d\n",m_Style);

         }

//纯虚函数

         virtual void OutputTitle()=0;

protected:

         int m_Style;

};

class Cb:public Ca

{

public:

         Cb(){ m_pTitle=NULL;}

         Cb(const char* Title,int Style=0);

         ~Cb()

         {

                            if(NULL!=m_pTitle)

                            delete[] m_pTitle;

          printf("~cb() called\n");

         }

        virtual void OutputStyle()

         {

          printf("%d\n",~m_Style);

         }

         virtual void OutputTitle()

         {  

                   if(NULL!=m_pTitle)

                   printf("%s\n",m_pTitle);

         }

private:

  char *m_pTitle;

};

Cb::Cb(const char* Title,int Style):Ca(Style)

{

         if(NULL==Title)

                   m_pTitle=NULL;

         else

         { m_pTitle=new char[strlen(Title)+1];

           strcpy(m_pTitle,Title);

         }

}

int main(int argc, char* argv[])

{

         Ca* pa=new Cb("Fairy");

 //调用基类定义的常规虚函数

//由于抽象基类不能实例化对象,只能通过类名限定的方法调用它的常规虚函数

         pa->Ca::OutputStyle(); 

//调用派生类重载的虚函数

         pa->OutputStyle();

         pa->OutputTitle();

//释放堆中的派生类对象,将首先调用派生类的析构函数

         delete pa;

         return 0;

}

程序输出结果:

0

-1

Fairy

~cb() called

~ca() called

抽象基类虽然不能实例化,但它可以定义整个类家族通用的成员变量和成员函数,为派生类提供一个框架。抽象基类为派生类提供了虚拟函数的重载形式,可以用抽象基类的指针引用派生类的对象,这为虚函数的应用准备了必要条件。

posted on 2011-05-09 18:02  carekee  阅读(451)  评论(0编辑  收藏  举报