虚函数、纯虚函数、虚基类

来源:互联网 发布:文件管理程序软件 编辑:程序博客网 时间:2024/05/16 18:56

1.虚函数是用于多态中virtual修饰父类函数,确保父类指针调用子类对象时,运行子类函数的。

2.纯虚函数是用来定义接口的,也就是基类中定义一个纯虚函数,基类不用实现,让子类来实现。

3.虚基类是用来在多继承中,如果父类继承自同一个父类,就只实例化一个父类(说的有点绕,就是只实例化一个爷爷的意思=。=)。

这个和多态有关,多态的定义不清楚的话到其他地方先了解一下,多态的三个必要条件:1.继承 2.重载 3.父类指针指向子类对象。


纯虚函数:

简单点说,纯虚函数就像java的接口,使用了纯虚函数的类不能被实例化,定义了纯虚函数的类不用写纯虚函数的实现,由子类实现,下面看代码:

class A  {  public:      virtual void printf() =0;  };  void A::printf()//纯虚函数可以不写实现  {      cout<<"printf A"<<endl;  }  class B : public A  {  public:      void printf(){          cout<<"printf B"<<endl;      }  };  int main(int argc, const char * argv[])  {      A *a =new A();//编译出错,纯虚函数的类不能实例化      a->printf();      return 0;  }  
virtual void printf() = 0;这是纯虚函数的写法,纯虚函数也是为多态服务的,它的作用是定义一个接口,让子类去实现。


虚基类

虚基类是c++独有的东西,因为c++中有多继承,也是关键字virtual相关的定义。

先来说说多继承,如果爷爷类(暂把父类的父类暂定为爷爷类= = ),父类继承自爷爷类。如果孙类继承自多个父类(听起来有点怪异),那么如果不使用虚基类,就会实例化多个爷爷类对象(越说越离奇),编译器会报错,说有歧义性。如果父类继承自虚基类,则可以解决多个父类不会实例化多个爷爷的问题,就是只有一个爷爷。可参看如下代码:

class Grandfather{  public:      int flag;      Grandfather(){          flag = 1;      }  };  class Father1:publicGrandfather{  public:      Father1(){          flag = 2;      }  };  class Father2:publicGrandfather{  public:      Father2(){          flag = 3;      }  };  class Son:public Father1,publicFather2{  };  int main(int argc, const char * argv[])  {      Son *son = new Son();      cout<<son->flag<<endl;//这里编译错误,没法指定flag是指定那一个,歧义      return 0;  }  


如果没有使用虚基类,多个父类继承自同一个爷爷类,就会产生歧义,到底是不是同一个爷爷?如果父类继承虚基类就不同了:


class Grandfather{  public:      int flag;      Grandfather(){          flag = 1;          cout<<"Grandfather flag = "<<flag <<endl;      }  };  class Father1:virtualpublicGrandfather{  public:      Father1(){          flag = 2;          cout<<"Father1 flag = "<<flag<<endl;      }  };  class Father2:virtualpublicGrandfather{  public:      Father2(){          flag = 3;          cout<<"Father2 flag = "<<flag<<endl;      }  };  class Son:public Father1,publicFather2{  };  int main(int argc, const char * argv[])  {      Son *son = new Son();      cout<<son->flag<<endl;      return 0;  }  

结果:

Grandfather flag = 1

Father1 flag = 2

Father2 flag = 3

现在,可以运行了,class Father2:virtual public Grandfather,就是继承虚基类的写法,爷爷对象只有一个,爷爷类的变量也只实例化了一次,那为什么最后打印出来的是3呢?看构造函数的顺序就可以看出来了,现在构造了爷爷类,再构造第一个继承的父类,最后继承第二个继承的父类,因此flag最后保持在第二个父类的修改值里了。



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝店铺销量为零怎么办 快递号填错卖家拒绝退款申请怎么办 淘宝店代购 售假怎么办 淘宝申请售后卖家没钱怎么办 淘宝禁止评价一个月怎么办 被卖家电话骚扰怎么办 恶意骚扰扣12分怎么办 新店开张交保证金被骗了怎么办 支付宝蚂蚁花呗逾期怎么办 被注销的微信怎么办 花呗有些不能用怎么办 实体店生意不好做怎么办 电器实体店生意越来越差怎么办 开业第一天不吉利怎么办 美容店开业第一天没人怎么办 淘宝店铺没有人访问怎么办 淘宝店铺没有人问怎么办 淘宝申请退款后店铺关闭怎么办 宝贝详情怎么改不了怎么办 改详情页后被删除宝贝怎么办 淘宝网商贷生意不好还不了怎么办 英国遗失在酒店物品怎么办 班福法则首位是0怎么办 同事能力比你强怎么办 新买的木板床响怎么办 笔记本键盘驱动坏了怎么办 云柜快递超时了怎么办 毕业设计被老师发现抄的怎么办 地板颜色太深了怎么办 皮质鞋子破皮了怎么办 吃了蜘蛛丝会怎么办 南京高二分班不公平怎么办? 高中分班考试没考好怎么办 实木门上的伸缩缝太深怎么办 mac点关机没反应怎么办 被压倒扁的易拉罐怎么办 白色车漏底漆了怎么办 客厅对着卧室门怎么办 老公不上进还懒怎么办 二胡按弦手指分不开怎么办 酷塑做完后疼痛怎么办