第三十九篇,C++的继承和派生,多继承的语法特性以及虚继承的概念的引出。

继承和派生
==============================================
   1.什么是继承,派生
         生活中:王思聪继承了王健林的资产
                 继承的好处,利用父辈打下的江山,继续努力奋斗,创造更好的业绩
         C++中:一个类继承另外一个类
                继承的好处,利用另外一个类已经写好的成员函数,复用代码
                            子类继承了父类,子类对象可以直接使用父类所有的成员方法(公有和保护)
                继承用来描述生活中is-a这种关系
                比如:  class Animal //动物类
                       {
                        public:
                           动物常用方法都写好了,动物跑,跳,吃,睡觉
                       }
                       class 自己写的类 继承 动物类
                       {
                             

                       }
              图形类  三角形  长方形  圆形
         派生:三角形继承了圆形类
               圆形类派生了三角形
         父类(基类): 圆形类就是父类
         子类(派生类):三角形就是子类

   2.语法规则
         class 子类名字:public     父类名字  //公有继承
         class 子类名字:private    父类名字  //私有继承
         class 子类名字:protected  父类名字  //保护继承
         {

              子类自己的内容
         };
         注意:三种继承方式,使用最多的是公有继承

   3.三种继承的区别
     第一种:公有继承 
          父类成员的权限   public        private     protected
          子类的内部        ok             no          ok
          子类的外部        ok             no          no   

     第二种:私有继承 
          父类成员的权限   public        private     protected
          子类的内部        ok             no          ok
          子类的外部        no             no          no    

     第三种:保护继承 
          父类成员的权限   public        private     protected
          子类的内部        ok             no          ok
          子类的外部        no             no          no  

  4.子类的大小(子类地址空间是如何组成的)
         子类的大小=父类大小+子类本身大小    也要满足字节对齐(跟结构体对齐规则一模一样)
    子类对象之所以可以调用父类的公有方法,原因就在于子类的地址空间中包含父类对象的一个副本,编译器是通过这个父类对象的副本去调用父类的公有方法
         子类对象.父类的公有方法()  //表面上看是利用子类对象去调用父类的公有方法
                                     实际上编译器是利用子类对象中包含的那个父类的副本去调用的

  5.继承之后,构造函数和析构函数的调用规则
         构造函数的调用的规则
                先调用父类的无参构造函数,然后再调用子类自己的构造函数
                注意:如果父类没有无参构造函数,编译器会报错
                      无论子类对象创建的时候是否传递了参数,父类都是使用无参构造
         析构函数的调用的规则
                先析构子类,再析构父类
    子类的构造函数可以使用参数列表的形式,去指定调用父类某个版本的构造函数
         例如:
              子类构造():父类构造(45,63)
          {
        cout<<"子类无参构造函数"<           }
          子类构造(int n):父类构造(n)
          {
        cout<<"子类有参构造函数,参数是: "<           }

  6.子类出现了跟父类同名的函数
        子类对象.函数名            //默认调用子类自己的同名函数
        子类对象.父类名::函数名;   //指定调用父类的同名函数


多继承
==============================================
   1.概念
         单继承:子类继承了一个父类
         多继承:子类继承了多个父类,描述生活中某个事物同时具备多个类的属性
                 豹子--》哺乳动物
                         猫科动物
                 圆桌--》圆形
                         桌子

   2.语法规则
         class 子类名:public 父类1,public 父类2,......   //如果还有其它的父类,继续往后写
         {

         }     
         
   3.多继承需要注意的点
         第一个:父类有多个,必须严格按照从左到右的顺序去看父类的调用顺序(计算子类大小也是要按照这个顺序去计算)

   4.多继承的特殊情况(虚继承)
         特殊情况:环状继承 
                   类A派生出类B,类C
                   类B,类C共同派生出类D
                           动物类A
                       哺乳B      猫科C
                            豹子D
         直接父类:
                 A是B的直接父类
                 B是D的直接父类
         间接父类:
                 A是D的间接父类
         环状继承引发的问题:
                问题一:创建子类D的对象,会导致A构建多次,浪费存储空间(理想情况是我只希望A构建一次)
                问题二:子类D的对象,调用A里面的方法,会引发二义性
                        二义性:编译器搞不清楚,你究竟是想要用B创建的A副本来调用,还是想要用C创建的A副本来调用

    5.虚继承解决刚才环状继承出现的两个问题
         虚继承的语法格式:
                子类:virtual public 父类  //虚继承
                {


                }   
         虚继承的底层原理(面试的时候常问到)
                一个类虚继承了另外一个类,那么在这个类的地址空间中会多出一个指针,该指针用来指向虚基类表的首地址
         虚基类: 被继承的那个类就是虚基类
         虚基类表:C++中开辟一块内存区域,专门用来存放所有的虚基类首地址的
                  用来存放虚基类首地址的一种数据结构  
 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部