*****水上飞机:继承,虚函数,虚继承

一题目

请设计以下航行器、飞机、船、水上飞机等 4 个类。

  • CRAFT 为航行器类,是公共基类,提供航行器的基本特性。包括:

    一个保护数据成员:speed(速度)。

    三个公有成员函数:构造函数(初始化速度)、析构函数和 Show 函数(显示速度)。

  • PLANE 为飞机类,以公有方式继承 CRAFT 类,在航行器类的基础上增加飞机的特性。包括:

    一个保护数据成员:width(翼展)。

    三个公有成员函数:构造函数(初始化速度和翼展)、析构函数和 Show 函数(显示速度和翼展)。

  • SHIP 为船类,以公有方式继承 CRAFT 类,在航行器类的基础上增加船的特性。包括:

    一个保护数据成员:depth(吃水深度)。

    三个公有成员函数:构造函数(初始化速度和吃水深度)、析构函数和 Show 函数(显示速度和吃水深度)。

  • SEAPLANE 为水上飞机类,同时以公有方式继承 PLANE 类和 SHIP 类,兼具飞机和船的特性。包括:

    三个公有成员函数:构造函数(初始化速度、翼展、吃水深度)、析构函数和 Show 函数(显示速度、翼展和吃水深度)。

  • 测试用例
  • 样例一
  •  CRAFT *p; p = new CRAFT(87.2); p->Show(); delete p; 
    创建航行器(速度: 87.2)
    航行(速度: 87.2)
    销毁航行器(速度: 87.2)
    
  • 样例二
  •  CRAFT *p; p = new PLANE(613.5, 45.3); p->Show(); delete p; 
    创建航行器(速度: 613.5)
    创建飞机(翼展: 45.3)
    航行(速度: 613.5, 翼展: 45.3)
    销毁飞机(翼展: 45.3)
    销毁航行器(速度: 613.5)
    
  • 样例三
  •  CRAFT *p; p = new SHIP(45.8, 8.3); p->Show(); delete p; 
    创建航行器(速度: 45.8)
    创建船(吃水: 8.3)
    航行(速度: 45.8, 吃水: 8.3)
    销毁船(吃水: 8.3)
    销毁航行器(速度: 45.8)
    
  • 样例四
  •  CRAFT *p; p = new SEAPLANE(415.2, 36.5, 2.1); p->Show(); delete p;
创建航行器(速度: 415.2)
创建飞机(翼展: 36.5)
创建船(吃水: 2.1)
创建水上飞机
航行(速度: 415.2, 翼展: 36.5, 吃水: 2.1)
销毁水上飞机
销毁船(吃水: 2.1)
销毁飞机(翼展: 36.5)
销毁航行器(速度: 415.2)

二.代码部分

#include <iostream>
using namespace std;
class CRAFT
{
protected:double speed;
public:CRAFT(double s){speed = s;cout << "创建航行器(速度: " << speed << ")" << endl;}virtual void Show(){cout << "航行(速度: " << speed << ")" << endl;}virtual ~CRAFT(){cout << "销毁航行器(速度: " << speed << ")" << endl;}
};
class PLANE :virtual public CRAFT
{
protected:double width;
public:PLANE(double s, double w) :CRAFT(s), width(w)//调用CRAFT的构造函数,传递speed{cout << "创建飞机(翼展: " << width << ")" << endl;}void Show()override{cout << "航行(速度: " << speed << ", 翼展: " << width << ")" << endl;}~PLANE()override{cout << "销毁飞机(翼展: " << width << ")" << endl;}
};
class SHIP :virtual public CRAFT
{
protected:double depth;
public:SHIP(double s, double d) :CRAFT(s), depth(d)//调用CRAFT的构造函数,传递speed{cout << "创建船(吃水: " << depth << ")" << endl;}void Show()override{cout << "航行(速度: " << speed << ", 吃水: " << depth << ")" << endl;}~SHIP()override{cout << "销毁船(吃水: " << depth << ")" << endl;}
};
class SEAPLANE : virtual public PLANE, virtual public SHIP
{
public:SEAPLANE(double s, double w, double d) :CRAFT(s), PLANE(s, w), SHIP(s, d)//调用CRAFT的构造函数,传递speed,调用 PLANE 的构造函数,传递 speed 和 width参数,调用 SHIP 的构造函数,传递 speed 和 depth参数{cout << "创建水上飞机" << endl;}void Show()override{cout << "航行(速度: " << speed << ", 翼展: " << width << ", 吃水: " << depth << ")" << endl;}~SEAPLANE()override{cout << "销毁水上飞机" << endl;}
};int main()
{double s, w, d;CRAFT* p;//CRAFT类型的指针cin >> s >> w >> d;p = new SEAPLANE(s, w, d);//实际指向SEAPLANE类的对象(未命名)p->Show();//调用SEAPLAENE的show函数delete p;return 0;
}

输出:

创建航行器(速度: 583.6)
创建飞机(翼展: 48.2)
创建船(吃水: 3.8)
创建水上飞机
航行(速度: 583.6, 翼展: 48.2, 吃水: 3.8)
销毁水上飞机
销毁船(吃水: 3.8)
销毁飞机(翼展: 48.2)
销毁航行器(速度: 583.6)

三总结

1.继承

方式

class 派生类:继承方式 基类

继承后的访问权限

 记忆方式:假设

public>protected>private

取基类属性和继承方式中较小的作为在派生类的访问属性

1.基类的pirvate在派生类中无法访问

2.基类的protected继承后可以在派生类中访问类外不行

2.虚函数

虚函数允许在派生类中重写基类的函数,从而实现运行的多态性

核心目的是通过基类访问派生类定义的函数,以便在通过基类指针引用或调用的时候可以执行派生类中的版本

#include<iostream>
using namespace std;
class A//基类
{
public:void foo(){cout << "1" << endl;}virtual void fun()//声明为虚函数virtual关键字{cout << "2" << endl;}
};
class B :public A//派生类
{
public:void foo()//隐藏:派生类的函数屏蔽了与其同名的基类函数{cout << "3" << endl;}void fun()//多态覆盖{cout << "4" << endl;}
};
int main()
{A a;B b;A* p = &a;//这里定义了一个指向 A 类的指针 p,并将其初始化为指向 a 对象的地址。p->foo();//输出1p->fun();//输出2p = &b;//我们将指针 p 的指向从 a 对象更改为 b 对象。注意,此时 p 仍然是一个指向 A 的指针,但它现在指向了 B 类的对象 b。p->foo();//取决于指针类型,定义为A类指针,故输出1p->fun();//取决于对象类型,指向了B的b对象,输出4(虚函数调用B类的fun)return 0;
}
总结     
  • 非虚函数(如 foo())在运行时不会被动态绑定。它们总是根据指针或引用的静态类型(即声明时的类型)来调用。
  • 虚函数(如 fun())在运行时会被动态绑定。它们会根据指针或引用实际指向的对象的类型来调用。
  • 仅在虚函数的顶层基类加上virtual关键字,子类不加,而改用override关键字

有了这方面的只是支持,我们现在来理解题目的输出部分:

1.构造函数不会被多态性影响。无论是通过基类指针还是派生类对象本身,构造函数总是会被调用,并且会调用基类的构造函数。

2.成员函数,当他们是虚函数时,他们被通过基类指针或调用引用时会表现出多态性,即会调用与指针或调用引用实际指向的对象类型相对应的函数版本。

3.析构函数,与构造函数类似,但与虚函数关系密切。如果基类的析构函数时虚函数时,则会表现出多态性,通过基类指针删除派生类对象时,会先调用派生类的析构函数,在调用基类的。如果基类的析构函数不是虚函数,那么只会调用基类的析构函数,这可能会导致派生类部分没有被正确清理,造成资源泄漏或其他问题。

3.虚继承

在C++中,虚继承是用于解决多重继承中公共基类(或称为“菱形继承”或“钻石问题”)的重复子对象问题的一种机制。当一个类(SEAPLANE)从多个类(SHIP,PLANE)继承,而这些类又都从一个公共基类(CRAFT)继承时,如果没有使用虚继承,那么该公共基类在派生类中将会有多个实例(或称为子对象),这通常不是我们想要的结果。

为了解决这个问题,C++引入了虚继承的概念。当某个基类被声明为虚继承时,它的所有派生类(无论是直接派生还是间接派生)都会共享这个基类的单一实例,而不是每个派生类都有自己的一个实例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3031626.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

算法学习笔记(一)-快速幂

#问题的引入-对于幂次方的求解我们怎么可以最大限度的降低时间复杂度呢 #对于一个基本的幂次运算&#xff0c;c代码如下示例 long long int myPower(int base,int power) {long long int result 1 ;for (int i 1 ; i < power ; i){result * base ;}return result ; } #…

LLMs应被视为一种文字计算器?

编者按&#xff1a;当前&#xff0c;大语言模型已经成为自然语言处理领域的热点。LLMs 是否真的“智能”&#xff1f;它们又为我们带来了哪些启发&#xff1f;针对这些问题&#xff0c;Darveen Vijayan 为我们带来了这篇引人深思的文章。 作者主要阐释了两个观点&#xff1a;第…

linux上用Jmter进行压测

在上一篇中安装好了Jmeter环境&#xff0c;在这一篇中将主要分享如何使用jmeter在linux中进行单机压测。 1.项目部署 在这里我们先简单部署一下测试环境&#xff0c;所用到的项目环境是个jar包&#xff0c;先在linux上home目录下新建app目录&#xff0c;然后通过rz命令将项目ja…

2万字干货:如何从0到1搭建一套会员体系(2)

2.用户等级 还是一样&#xff0c;我们为什么要搭建用户等级&#xff1f; 一个国家有几亿人口的时候你怎么来管理&#xff1f;老祖宗秦始皇给出了我们答案&#xff1a;郡县制。发展到现在则演进成了省-市-区县-乡镇(街道)-村(社区)5层行政治理结构。 产品同理&#xff0c;当你…

Flume 的安装和使用方法(Spark-2.1.0)

一、Flume的安装 1.下载压缩包 https://www.apache.org/dyn/closer.lua/flume/1.7.0/apache-flume-1.7.0-bin.tar.gz 2.上传到linux中 3.解压安装包 cd #进入加载压缩包目录sudo tar -zxvf apache-flume-1.7.0-bin.tar.gz -C /usr/local # 将 apache-flume-1.7.0-bin.tar.g…

文旅行业| 某景区导游培养和管理项目成功案例纪实

——整合导游资源并进行统一管理&#xff0c;构建完善的培养与管理机制&#xff0c;发挥景区导游价值 【客户行业】文旅行业&#xff1b;景区&#xff1b;文旅企业 【问题类型】人才培养&#xff1b;人员管理 【客户背景】 南方某5A级景区&#xff0c;作为国内极具代表性和特…

经常睡不好觉?试试用上华为手环9新升级的睡眠监测功能

睡眠问题是不是经常困扰着你呢&#xff1f;听说&#xff0c;华为手环9的睡眠监测功能升级了&#xff0c;无论是入睡前、睡眠中还是睡醒后&#xff0c;都能够帮助我们改善睡眠&#xff0c;让我们告别糟糕的睡眠质量&#xff01; 睡觉前&#xff0c;打开华为手环9的睡眠模式&…

寻找最大价值的矿堆 - 矩阵

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、Java代码五、测试用例 前言 本人最近再练习算法&#xff0c;所以会发布一些解题思路&#xff0c;希望大家多指教 一、题目描述 给你一个由’0’(空地)、‘1’(银矿)、‘2’(金矿)组成的地图…

自动化测试基础 --- Jmeter

前置环境安装 首先我们需要知道如何下载Jmeter 这里贴上下载网站Apache JMeter - Download Apache JMeter 我们直接解压,然后在bin目录下找到jemter.bat即可启动使用 成功打开之后就是这个界面 每次打开可以用这种方式切换成简体中文 或者直接修改properties文件修改对应的语言…

第七届精武杯部分wp

第一部分&#xff1a;计算机和手机取证 1.请综合分析计算机和手机检材&#xff0c;计算机最近一次登录的账户名是 答案&#xff1a;admin 创建虚拟机时直接给出了用户名 2. 请综合分析计算机和手机检材&#xff0c;计算机最近一次插入的USB存储设备串号是 答案&#xff1a…

01面向类的讲解

指针指向类成员使用 代码&#xff1a; #include<iostream> using namespace std;class Test { public:void func() { cout << "call Test::func" << endl; }static void static_func();int ma;static int mb; //不依赖对象 }; void Test::static…

探索GitHub上的GPTs项目:泄露和被破解的GPT提示

GPTs项目是一个在GitHub上由用户linexjlin发起的开源项目&#xff0c;专注于提供泄露的GPT&#xff08;生成式预训练转换器&#xff09;提示。这些提示用于指导和优化AI模型的输出&#xff0c;进而提升代码生成的质量和效率。项目页面提供了丰富的功能和资源&#xff0c;旨在帮…

全套停车场管理系统报价多少钱?停车场管理系统由哪些设备组成?

随着城市化进程的加快&#xff0c;汽车保有量的不断攀升&#xff0c;停车场的管理和运营成为城市基础设施建设的重要组成部分。一个高效、智能的停车场收费系统不仅能提升停车效率&#xff0c;还能增强用户体验&#xff0c;对城市的交通管理起到关键作用。本文将为您详细介绍全…

mac 讨厌百度网盘怎么办

一、别拦我 首先请允许我泄个愤&#xff0c;tmd百度网盘下个1g的文件下载速度竟然超不过200k&#xff0c;只要不放在所有已打开软件的最前面&#xff0c;它就给你降到10k以内&#xff0c;关键是你慢就慢了&#xff0c;我也不是很着急&#xff0c;关键是你日常下载失败并且总是…

AI代理和AgentOps生态系统的剖析

1、AI代理的构成&#xff1a;AI代理能够根据用户的一般性指令自行做出决策和采取行动。 主要包含四个部分&#xff1a; &#xff08;1&#xff09;大模型&#xff08;LLM&#xff09; &#xff08;2&#xff09;工具&#xff1a;如网络搜索、代码执行等 &#xff08;3&#x…

在Qt工具栏上实现矩阵并排的按钮效果源码

如果这个要用MFC去实现头皮都得掉一层&#xff0c;建议大家以后要写GUI方面的小工具尽量转QT或其他吧&#xff0c;MFC真不适合搞这种花里胡哨的界面. 在Qt工具栏上实现矩阵并排的按钮效果源码如下&#xff1a; #include "mainwindow.h" #include "ui_mainwind…

初识指针(4)<C语言>

前言 前面的文章&#xff0c;已经对指针的基础概念以及运用有了初步了解&#xff0c;我们可以进一步探究指针比较深入的知识&#xff0c;下文将主要介绍&#xff1a;使用指针数组模拟二维数组、字符指针变量、数组指针、二维数组传参的本质、函数指针、typedef关键字等。 目录…

RustDesk 自建服务器部署和使用教程

RustDesk 是一个强大的开源远程桌面软件&#xff0c;是中国开发者的作品&#xff0c;它使用 Rust 编程语言构建&#xff0c;提供安全、高效、跨平台的远程访问体验。可以说是目前全球最火的开源远程桌面软件了&#xff0c;GitHub 星星数量达到了惊人的 64k&#xff01; 与 Team…

洪水仿真模拟(ArcGIS),水利数字孪生新利器

这两天ArcGIS Pro的官方账号释放了一个名为“Flood Simulation in ArcGIS Pro”的洪水模拟功能视频。根据视频详情页的介绍&#xff0c;该洪水仿真模拟功能会作为新功能出现在ArcGIS Pro 3.3中。 由于我目前从事的主要应用方向都是弱GIS的领域&#xff0c;所以我已经很久没有再…