虚函数与纯虚函数的区别


虚函数为了重载和多态的需要,函数在基类中是有定义的。即便是个空函数,也可以在子类中覆盖这个基类的函数。


纯虚函数在基类中是没有定义的,必须在子类中来实现。



虚函数引入的原因是为了方便使用多态:


class Animal{

.....

    public:

    virtual void speak(){cout<<"umum"<<endl;}

    virtual void run(){cout<<"run!"<<endl;}

};


class Human:public Animal{

......

     public:

     virtual void speak(){cout<<"你好!"<<endl;};

};

class Cat:public Animal{

    ......

    public:

    virtual void speak(){coout<<"喵喵~~"<<endl;

};


class Dog:public Animal{

      ......

     public:

      virtual void speak(){cout<<"汪汪~"<<endl;}

};


上面的这个简单的例子就可以说明虚函数的简单性质。


以下是调用的时候:


int main{


Animal an,*pan;

       Human hu,*phu;

       Cat ca,*pca;

       Dog dog,*pdo;

       //这是虚函数的精彩的地方,如果没有指针,没有        // 多大意思。

      pan=&an;

      phu=&hu;

      pca=&ca;

      pdo=&dog;

      pan->speak();//umum

      phu->speak();//你好

      pca->speak();//喵喵

      pdo->speak();//汪汪

      pan->run();

      phu->run();

      pca->run();

      pdo->run();//子类中没有重实现该函数,调用基                  //类中的。

      Cat *p;

      p=&an;

      // 这个地方会报错: 从类型‘Animal*’到类型‘Cat*’的转换无效

      //p->speak();

//但是

      Animal *p1;

      p1=&ca;

      p1->speak();//喵喵

      //可以把Cat看成是Animal的对象

      //子类可以调用父类的成员函数,但父类不可以调用子类的

}



纯虚函数:

通过简单的修改,下面就是纯虚函数的使用方法:

class Animal{

.....

    public:

    virtual void speak()=0;

    virtual void run()=0;

//以上两个成员函数都只能在子类中才能实现

};


class Human:public Animal{

......

     public:

     void speak(){cout<<"你好!"<<endl;}

     void run(){cout<<"直立行走"<<endl;}

};

class Cat:public Animal{

    ......

    public:

    void speak(){cout<<"喵喵~~"<<endl;

    void run(){cout<<"优雅的走!"<<endl;}

};


class Dog:public Animal{

      ......

     public:

     void speak(){cout<<"汪汪~"<<endl;}


};




int main{


// Animal an,*pan;

//Animal 成了抽象类,就不能实例化了。

//成员函数也只能在子类中进行实例化。

       Human hu,*phu;

       Cat ca,*pca;

       Dog dog,*pdo;

       //纯虚函数 也得使用指针。

      phu=&hu;

      pca=&ca;

      pdo=&dog;

      phu->speak();//你好

      pca->speak();//喵喵

      pdo->speak();//汪汪

      phu->run();直立行走

      pca->run();优雅的走

      // pdo->run(); //子类中没有实现 不能调用

      Ca *p=&dog;

      p->speak();//会出现错误 不能在初始化时将‘Dog*’转换为‘Cat*’

   }