c++的多重继承

2023-05-16

一、前言
每个类只继承一个父辈,在现实世界中事情通常是这样的,但是有一些类却代表两个类的合成。例如两用沙发,它是一张床,也是一个沙发。

二、示例代码,用作下面提出问题使用

#include<iostream>
using namespace std;

class Bed
{
protected:
    int weight;
public:
    Bed() :weight(0) {}
    void setWeight(int i) { weight = i; }
    void sleep()
    {
        cout << "Sleeping....." << endl;
    }
};

class Sofa
{
protected:
    int weight;
public:
    Sofa() :weight(0) {}
    void setWeight(int i) { weight = i; }
    void watchTV()
    {
        cout << "Watch TV ..." << endl;
    }
};

class Bed_And_Sofa :public Bed, public Sofa
{
public:
    Bed_And_Sofa() {}
    void Foldout()
    {
        cout << "Fold Out.." << endl;
    }
};

int main()
{
    Bed_And_Sofa a;
    a.watchTV();
    a.sleep();
    a.Foldout();
    cin.get();
    return 0;
}

三、继承的模糊性
我们从示例代码中,可以发现他们共用的变量是weight,这样我们就不知道Bed_And_Sofa到底是继承哪一个,或者是两个都继承,那么你在使用的时候,使用哪个了?这样会造成weight的引用变的模糊。例如如下代码块:

//为了修改weight的值,只有在主函数中输入如下代码,确定修改那个基类的weight
int main()
{
    Bed_And_Sofa a;
    a.Sofa::setWeight(20);
}

如上的方式是可以解决,多继承带来的模糊性问题,但是这也增加了程序员的压力。

四、虚拟继承
从意义上来分析,我们刚才提出的两个例子,并没有什么现实生活的意义。但是我们都知道家具都是有重量的。所以我们把示例代码重新编写:

#include<iostream>
using namespace std;
class Furniture
{
public :
    Furniture() {}
    void setWeight(int i)
    {
        weight = i;
    }
    int getWeight()
    {
        return weight;
    }
protected:
    int weight;
};

class Bed:public Furniture
{
protected:
    int weight;
public:
    Bed() :weight(0) {}
    void sleep()
    {
        cout << "Sleeping....." << endl;
    }
};

class Sofa:public Furniture
{
protected:
    int weight;
public:
    Sofa() :weight(0) {}
    void watchTV()
    {
        cout << "Watch TV ..." << endl;
    }
};

class Bed_And_Sofa :public Bed, public Sofa
{
public:
    Bed_And_Sofa() {}
    void Foldout()
    {
        cout << "Fold Out.." << endl;
    }
};

int main()
{
    Bed_And_Sofa a;
    a.setWeight(10);           //程序编译不通过,因为这里的Furniture是一个不确定的值,我们不知道给f返回Bed继承的还是Sofa继承的。
    Furniture * f;
    f = (Furniture *)&a;    //程序编译不通过,因为这里的Furniture是一个不确定的值,我们不知道给f返回Bed继承的还是Sofa继承的。
    cin.get();
    return 0;
}

对于上述的问题,我们发现Bed_And_Sofa继承了两个Furniture类,出现了模糊继承的。所以为了解决这个问题,我们提出了虚拟继承。修改上述代码:

#include<iostream>
using namespace std;
class Furniture
{
public :
    Furniture() {}
    void setWeight(int i)
    {
        weight = i;
    }
    int getWeight()
    {
        return weight;
    }
protected:
    int weight;
};

class Bed:virtual public Furniture   //虚拟继承
{
protected:
    int weight;
public:
    Bed() :weight(0) {}
    void sleep()
    {
        cout << "Sleeping....." << endl;
    }
};

class Sofa :virtual public Furniture   //虚拟继承
{
protected:
    int weight;
public:
    Sofa() :weight(0) {}
    void watchTV()
    {
        cout << "Watch TV ..." << endl;
    }
};

class Bed_And_Sofa :public Bed, public Sofa
{
public:
    Bed_And_Sofa() {}
    void Foldout()
    {
        cout << "Fold Out.." << endl;
    }
};

int main()
{
    Bed_And_Sofa a;
    a.setWeight(10);    
    Furniture * f;
    f = (Furniture *)&a;    
    cout << f->getWeight() << endl;
    cin.get();
    return 0;
}

修改后的程序可以正常的执行,到底虚拟继承做了声明可以让程序正常执行了,下面我们给出Bed_And_Sofa的内存布局,你就明白了
这里写图片描述
所以virtual只是告诉系统,如果之前没有别人继承Furniture的话,那么就在加入一个Furniture拷贝,否则就用之前拷贝的那个。

五、多继承的构造顺序
(1)任何虚拟基类构造函数按照继承顺序构造
(2)任何非虚拟基类构造函数按照继承顺序构造
(3)任何成员对象的构造函数按照他们 的声明方式构造
(4)类自己的构造函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++的多重继承 的相关文章

随机推荐

  • ardupilot在Linux上设置SITL(FlightGear)

    本页介绍如何在Linux上设置SITL xff08 软件在环路中 xff09 特定命令在Ubuntu上从12 10到16 04进行了测试 概观 SITL模拟器允许您在没有任何硬件的情况下运行Plane xff0c Copter或Rover
  • px4+vins+ego单机鲁棒飞行二(外部位姿估计篇)

    px4 43 vins 43 ego单机鲁棒飞行二 xff08 外部位姿估计篇 xff09 一 使用px4的EKF2 xff08 扩展卡尔曼 xff09 估计测试过程及结果 xff1a 二 使用px4的LPE估计测试过程及结果 xff1a
  • px4+vins+ego单机鲁棒飞行三(realsense_ros配置及经验篇)

    px4 43 vins 43 ego单机鲁棒飞行三 xff08 realsense ros配置及经验篇 xff09 一 驱动及realsense ros安装二 参数设置三 经验 一 驱动及realsense ros安装 D435i标定摄像头
  • px4+vins+ego单机鲁棒飞行四(PX4飞控日志分析篇)

    px4 43 vins 43 ego单机鲁棒飞行四 xff08 PX4飞控日志分析篇 xff09 一 FlightPlot安装二 记录日志二 取出日志三 分析日志 一 FlightPlot安装 参考博客 参考视频 二 记录日志 在QGC中参
  • px4+vins+ego单机鲁棒飞行二-1(更改px4外部视觉估计固件)

    px4 43 vins 43 ego单机鲁棒飞行二 1 xff08 更改px4外部视觉估计固件 xff09 一 EKF2源码 获取视觉里程计信息二 EKF2源码 设置外部视觉数据三 源码中对位置的发送四 测试 前提 xff1a 固件1 11
  • px4+vins+ego单机鲁棒飞行五(坐标系变换篇)

    px4 43 vins 43 ego单机鲁棒飞行五 xff08 坐标系变换篇 xff09 一 齐次矩阵变换原理二 无人机上利用旋转矩阵求飞机中心位置 一 齐次矩阵变换原理 参考一 参考二 二 无人机上利用旋转矩阵求飞机中心位置 首先写出相机
  • 编译多版本opencv,并在cmakelists中链接

    编译多版本opencv xff0c 并在cmakelists中链接 一 下载二 编译三 链接四 替代系统的 xff08 可选 xff0c 但不建议 xff09 五 链接了 xff0c 但无法找到 一 下载 github链接 自己选择版本 x
  • CMakeLists笔记

    CMakeLists笔记 一 路径名二 函数三 常用 一 路径名 PROJECT SOURCE DIR xff1a 一般为catkin ws src xff0c 是cmakelists的绝对路径PROJECT BINARY DIR xff1
  • 源码编译安装openvino

    源码编译安装openvino 1 原地升级cmake2 编译opencv4 5 33 下载openvino4 配置usb规则 参考博客 交叉编译方式 1 原地升级cmake 方法一 xff1a 下载3 19 0中的CMake 3 19 0
  • 【ros】读取串口数据

    文章目录 一 自定义 gnrmc msg二 代码三 结果四 注意点 有时候 有的设备是通过串口发送数据 xff0c 想要在 ros 中 xff0c 读取串口数据 xff0c 记录一下操作 xff1a 一 自定义 gnrmc msg 首先需要
  • Android守护进程

    守护进程 守护进程 一直在后台运行的进程 本文主要讲解一些android比较常用的守护进程的方法 实现思想 1 保活 xff0c 通过提高进程优先级 xff0c 降低进程被杀死的概率 2 拉起 xff0c 进程被杀死后 xff0c 进行拉起
  • ros package 由于依赖 msg 导致编译问题解决

    文章目录 1 问题2 解决 1 问题 经常我们会自定义一些 msg 给其他的 package 使用 如果正常写 CmakeLists txt 在编译的时候 就会提示没有找到依赖的 msg 需要先编译 msg 的 package 再编译其他的
  • 使用Docker部署软件运行环境

    什么是docker xff1f Docker是基于Go语言进行开发实现 xff0c 一个开源的应用容器引擎 采用Linux内核的cgroup xff0c namespace xff0c 以及AUFS类的Union FS等技术 xff0c 对
  • 【控制control】四足机器人运动学、动力学模型

    系列文章目录 提示 xff1a 这里可以添加系列文章的所有文章的目录 xff0c 目录需要自己手动添加 TODO 写完再整理 文章目录 系列文章目录前言一 四足机器人实际模型的物理难点二 四足机器人运动学模型1 方法一 xff1a DH法建
  • 【项目解读】fast_planner工程解读

    系列文章目录 提示 xff1a 这里可以添加系列文章的所有文章的目录 xff0c 目录需要自己手动添加 TODO 写完再整理 文章目录 系列文章目录前言一 规划系统运行逻辑 业务部分 1 Fast planner node cpp 程序入口
  • IMU方向位姿估计

    系列文章目录 提示 xff1a 这里可以添加系列文章的所有文章的目录 xff0c 目录需要自己手动添加 TODO 写完再整理 文章目录 系列文章目录前言一 方法一 xff1a IMU方向位姿可以直接从IMU本身提供的专有算法中获得 xff0
  • 【autoware的仿真平台】

    系列文章目录 提示 xff1a 这里可以添加系列文章的所有文章的目录 xff0c 目录需要自己手动添加 TODO 写完再整理 文章目录 系列文章目录前言一 仿真的必要性及常见的仿真工具介绍二 gazebo仿真插件介绍及源码解析1 gazeb
  • 【机械臂、无人机规控篇】(8)机械臂轨迹规划、跟踪控制方向

    系列文章目录 提示 xff1a 这里可以添加系列文章的所有文章的目录 xff0c 目录需要自己手动添加 TODO 写完再整理 文章目录 系列文章目录前言一 机械臂的规划控制和无人的规划控制的异同点分析1 规划的异同分析2 控制的异同分析 二
  • 微信支付——支付签名验证失败的坑

    只讲几个微信支付开发中的签名问题 xff08 JAVA版的公众号支付 xff09 第一个是获取订单数据时生成 xff0c 然后通过这些数据生成预支付订单 xff08 通过 统一下单 方法取得 xff09 xff0c 微信官方返回一串xml数
  • c++的多重继承

    一 前言 每个类只继承一个父辈 xff0c 在现实世界中事情通常是这样的 xff0c 但是有一些类却代表两个类的合成 例如两用沙发 xff0c 它是一张床 xff0c 也是一个沙发 二 示例代码 xff0c 用作下面提出问题使用 span