十八、纯虚函数和抽象类

1.基本概念

  • 纯虚函数是一个在基类中说明的虚函数,在基类中没有定义,要求任何派生类都定义自己的版本

  • 纯虚函数为个派生类提供一个公共界面(接口的封装和设计、软件的模块功能划分)

纯虚函数的语法

virtual 类型 函数名(参数表) = 0 

一个具有纯虚函数的基类称为抽象类

2.纯虚函数和抽象类

//图形类
//拥有纯虚函数的类,称为抽象类
class Shape
{
public:
//是一个抽象的接口,说明图形是有一个得到面积的方法
   virtual double getArea() = 0;//一个求图形面积的接口

   virtual double printArea() = 0;//定义一个打印面积的接口

};

//圆类
//如果一个子类继承了抽象类,那么一定要重写这个纯虚函数
class Circle:public Shape
{
public:
   Circle(double r){
      this->r = r;
   }
   virtual double getArea(){
       return 3.14*r*r;
   }

  virtual void printArea(){
     cout<<"圆的面积是:"<<this->getArea()<<endl;
  }

private:
    double r;//半径

};

//实现一个正方形
class Rect:public Shape
{
public:
   Rect(int a){
      this->a =a;
   }

    virtual double getArea() {
          return a*a;
   }

   virtual double printArea() {
       cout<<"正方形的面积是:"<<this->getArea()<<endl;
   }
private:
    int a;//边长
};


//一个传递抽象类指针的架构函数
void PrintArea(Shape *p){
 //抽象类的指针就可以调用纯虚函数接口
  //  cout<<sp->getArea()<<endl;//在此处发生了多态

   p->printArea();
}



int main(void)
{
  Shape *s;//报错!纯虚函数不可被实例化

  Shape *sp = new Circle(2.0);
 
  printArea(sp);
  
  delete sp;

 sp = new Rect(10);

  //创建一个正方形的对象,用抽象类指针(父类指针)指向子类对象
  printArea(sp);

  delete sp;

  return 0;
}


  • 含有纯虚函数的类,称为抽象基类,不可实列化。即不能创建对象,存在 的意义就是被继承,提供族类的公共接口。
  • 纯虚函数只有声明,没有实现,被“初始化”为0。
  • 如果一个类中声明了纯虚函数,而在派生类中没有对该函数定义,则该虚函数在派生类中仍然为纯虚函数,派生类仍然为纯虚基类。

3.多继承和抽象类

  • 绝大多数面向对象语言都不支持多继承,绝大多数面向对象语言都支持接口的概念
  • C++中没有接口的概念,C++中可以使用纯虚函数实现接口
  • 接口类中只有函数原型定义,没有任何数据的定义
//抽象类1
class Interface1
{
public:
    //纯虚函数
    virtual void func(int a,int b) = 0;
    virtual void func2(int a) = 0;
};

//抽象类2
class Interface2
{
public:
    //纯虚函数
    virtual void func(int a,int b) = 0;
};

//当纯虚函数在多继承中出现了重复,那么在子类中只要重新重写一次就可以了
class Child:public Interface1,public Interface2
{
public:
   virtual void func(int a,int b)
   {
    cout<<"a = "<<a<<" b = "<<b<<endl;
   }

   virtual void func2(int a){
      cout<<"a = "<<a<<endl;
  }

};

int main(void)
{

  Child c;
  c.func(10,20);

  Interface *if1 = new Child;
  if1->func(10,20);
  if1->func2(100);

  Interface *if2 = new Chiild;
  if2->func(20,30);
 //if2没办法调func2,因为他没有!
  return 0;
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • C++虚函数 C++虚函数是多态性实现的重要方式,当某个虚函数通过指针或者引用调用时,编译器产生的代码直到运行时才...
    小白将阅读 1,755评论 4 19
  • 参考来源:知乎 定义一个函数为虚函数,不代表函数为不被实现的函数。定义他为虚函数是为了允许用基类的指针来调用子类的...
    夜幕青雨阅读 856评论 0 6
  • 仿佛经历了一次漫长的冬眠,亦或是起死回生,我从混沌中睁开了眼。 站在镜子前,看着自己心口上长长的一道痕迹,我问旁边...
    王半天阅读 731评论 0 47
  • 程序员必备基础知识点(活到老学到老的知识点) 算法和数据结构 LeetCode 算法导论 剑指 offer 计算机...
    XcqRomance阅读 3,513评论 0 193
  • 董小姐发飙记 万圣节前的10月28日,格力临时股东大会上董小姐发飙的新闻成为这两天的热门话题,因为董小姐进门时,没...
    何小英_Monica阅读 1,914评论 0 2