zoukankan      html  css  js  c++  java
  • 继承(day09)

    二十一 继承(Inheritance)
    ...
    5 子类的构造函数和析构函数
    5.1 子类的构造函数
    1)如果子类构造函数没有显式指明基类子对象的初始化方式,那么该子对象将以无参方式被初始化。
    2)如果希望基类子对象以有参的方式被初始化,必须在子类构造函数的初始化表中显式指明。
      class 子类:public 基类{
         子类(...):基类(基类子对象构造实参表){}
      };
    3)子类对象的构造过程
    --》分配内存
    --》构造基类子对象(按继承表顺序)
    --》构造成员子对象(按声明顺序)
    --》执行子类的构造代码
    
    5.2 子类的析构函数
    1)子类的析构函数,会自动调用基类的析构函数,析构基类子对象。
    2)子类对象的销毁过程
    --》执行子类的析构代码
    --》析构成员子对象(按声明逆序)
    --》析构基类子对象(按继承表逆序)
    --》释放内存
    3)基类析构函数不能调用子类的析构函数,对一个指向子类对象的基类指针使用delete运算符,实际被执行的仅是基类的析构函数,所释放的仅是基类子对象构造时的分配的动态资源,而子类特有的动态资源将会形成内存泄露。
    eg:
    class A{
        A(void){动态资源分配}
        ~A(void){动态资源销毁}
    };
    class B:class A{
        B(void){动态资源分配}
        ~B(void){动态资源销毁}
    };
    A* pa = new B;//pa:指向子类对象的基类指针
    delete pa;//子类析构函数执行不到,内存泄露
    -------------------------
    6 子类的拷贝构造和拷贝赋值
    6.1 子类的拷贝构造
    1)子类没有定义拷贝构造函数,编译器会为子类提供缺省拷贝构造函数,该函数会自动调用基类的拷贝构造函数,初始化基类子对象。
    2)子类定义拷贝构造函数,需要使用初始化表,显式指明基类子对象也以拷贝方式进行初始化。
    6.2 子类的拷贝赋值
    1)子类没有定义拷贝赋值操作符函数,编译器会提供缺省拷贝赋值函数,该函数会自动调用基类的拷贝赋值函数,复制基类子对象。
    2)子类定义拷贝赋值操作符函数,需要显式调用基类的拷贝赋值函数,完成对基类子对象的复制。 
    
    7 多重继承
    1)一个子类继承多个基类,这样继承方式称为多重继承。
    eg:
     技术员   经理
               /
          技术主管
    eg:
     电话  播放器  计算机
            |     /
         智能手机
         
    2)向上造型时,编译器会根据各个基类子对象在子类对象中内存布局,进行适当的偏移计算,保证指针的类型和其所指向的目标对象类型一致。
    
    3)名字冲突问题
      一个子类的多个基类存在相同的名字,当通过子类访问这些名字时,编译器会报歧义错误--名字冲突。
      解决名字冲突的通用做法就是显式地通过作用域限定,指明所访问的名字属于哪一个基类。
      如果产生冲突的名字是成员函数,并且参数不同,也可以通过using声明,让其在子类中形成重载,通过函数重载匹配解决冲突问题。
    
    8 钻石继承
    1)一个子类的多个基类源自共同的祖先基类,这样继承结构称为钻石继承。
       A(m_data)
      / 
     B   C
       /
       D
    2)公共基类(A)子对象,在汇聚子类(D)对象中,存在多个实例。在汇聚子类中,或者通过汇聚子类对象,去访问公共基类的成员,会因为继承路径不同而导致结果不一致。
    3)通过虚继承可以让公共基类(A)子对象,在汇聚子类(D)对象中的实例唯一,并且为所有子类共享,这样即使沿着不同的继承路径去访问公有基类的成员,结果也是一致的。
    
    9 虚继承的语法
       A(m_data)
      / 
     B   C(virtual)
       /
       D(负责构造虚基类子对象)
    1)在继承表中使用virutal关键字
    2)由汇聚子类的构造函数负责构造虚基类子对象
    3)公共基类的所有子类,都必须在构造函数的初始化表中显式指明其初始化方式,否则编译器将会选择以无参方式初始化。
    
    ----------------------------
    练习:薪资计算
                员工
            /     |      
        技术员  经理  销售员
              /       /
         技术主管  销售主管
    所有员工:姓名、工号、职位等级、出勤率
    经理:绩效奖金(元/月)
    技术员:研发津贴(元/小时)
    销售员:提成比率(x%)
    
    薪资=基本工资+绩效工资
    基本工资计算=职位等级的固定额度*出勤率(输入);
    绩效工资根据具体的职位而定:
    普通员工:基本工资一半
    经理:绩效奖金*绩效因数(输入)
    技术员:研发津贴*工作小时数*进度因数(输入)
    销售员:提成比率*销售额度(输入)
    
    技术主管:(技术员绩效工资+经理绩效工资)/2
    销售主管:(销售员绩效工资+经理绩效工资)/2
    
    结果:打印员工信息,输入必要数,计算和打印工资

     

  • 相关阅读:
    平面划分问题
    First Missing Positive
    Redis.conf
    Redis内存存储结构分析
    IE9崩溃解决办法
    未能正确加载包"visla Studio HTM Editor Package"(GUID={1B437B20F8FE11D2A5AE00104BCC7269})
    SQL SERVER 数据类型详解
    创建TIff虚拟打印机
    VS2010出现错误the operation could not be completed
    C# 基础知识 20101118
  • 原文地址:https://www.cnblogs.com/Kernel001/p/7729884.html
Copyright © 2011-2022 走看看