zoukankan      html  css  js  c++  java
  • C++基类与派生类的转换

    只有公用派生类才是基类真正的子类型,它完整地继承了基类的功能。基类与派生类对象之间有赋值兼容关系,由于派生类中包含从基类继承的成员,因此可以将派生类的值赋给基类对象,在用到基类对象的时候可以用其子类对象代替。

    具体表现在以下几个方面:

    1派生类对象可以向基类对象赋值
      可以用子类(即公用派生类)对象对其基类对象赋值。如
    A a1; //定义基类A对象a1
    B b1; //定义类A的公用派生类B的对象b1
    a1=b1; //用派生类B对象b1对基类对象a1赋值
    在赋值时舍弃派生类自己的成员

    实际上,所谓赋值只是对数据成员赋值,对成员函数不存在赋值问题。请注意: 赋值后不能企图通过对象a1去访问派生类对象b1的成员,因为b1的成员与a1的成员是不同的。

    假设age是派生类B中增加的公用数据成员,分析下面的用法:
      a1.age=23;//错误,a1中不包含派生类中增加的成员
       b1.age=21; //正确,b1中包含派生类中增加的成员
    应当注意,子类型关系是单向的、不可逆的。B是A的子类型,不能说A是B的子类型。

     只能用子类对象对其基类对象赋值,而不能用基类对象对其子类对象赋值,理由是显然的,因为基类对象不包含派生类的成员,无法对派生类的成员赋值。同理,同一基类的不同派生类对象之间也不能赋值。

    2.派生类对象可以替代基类对象向基类对象的引用进行赋值或初始化。
    如已定义了基类A对象a1,可以定义a1的引用变量:
    A a1; //定义基类A对象a1
    B b1; //定义公用派生类B对象b1
    A& r=a1; //定义基类A对象的引用变量r,并用a1对其初始化
    这时,引用变量r是a1的别名,r和a1共享同一段存储单元。也可以用子类对象初始化引用变量r,将上面最后一行改为
    A& r=b1;//定义基类A对象的引用变量r,并用派生类B对象b1//对其初始化
    或者保留上面第3行“A& r=a1;”,而对r重新赋值:
    r=b1;//用派生类B对象b1对a1的引用变量r赋值

    注意: 此时r并不是b1的别名,也不与b1共享同一段存储单元。它只是b1中基类部分的别名,r与b1中基类部分共享同一段存储单元,r与b1具有相同的起始地址

    3.如果函数的参数是基类对象或基类对象的引用,相应的实参可以用子类对象。如有一函数
    fun: void fun(A& r)//形参是类A的对象的引用变量
    {
    cout<<r.num<<endl;
    } //输出该引用变量的数据成员num

    函数的形参是类A的对象的引用变量,本来实参应该为A类的对象。由于子类对象与派生类对象赋值兼容,派生类对象能自动转换类型,在调用fun函数时可以用派生类B的对象b1作实参: fun(b1); 输出类B的对象b1的基类数据成员num的值。与前相同,在fun函数中只能输出派生类中基类成员的值。

    4.派生类对象的地址可以赋给指向基类对象的指针变量,也就是说,指向基类对象的指针变量也可以指向派生类对象。

  • 相关阅读:
    python enhanced generator - coroutine
    python yield generator 详解
    gunicorn syncworker 源码解析
    gunicorn 信号处理(SIGHUP,SIGUSR2)
    gunicorn Arbiter 源码解析
    gunicorn 简介
    kafka+zookeeper环境配置(linux环境单机版)
    在Linux中安装JDK的步骤
    Kafka安装及部署
    Zookeeper 安装和配置
  • 原文地址:https://www.cnblogs.com/youxin/p/2567841.html
Copyright © 2011-2022 走看看