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

news2024/11/19 19:40:01

一题目

请设计以下航行器、飞机、船、水上飞机等 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();//输出1
	p->fun();//输出2
	p = &b;//我们将指针 p 的指向从 a 对象更改为 b 对象。注意,此时 p 仍然是一个指向 A 的指针,但它现在指向了 B 类的对象 b。
	p->foo();//取决于指针类型,定义为A类指针,故输出1
	p->fun();//取决于对象类型,指向了B的b对象,输出4(虚函数调用B类的fun)
	return 0;
}
总结     
  • 非虚函数(如 foo())在运行时不会被动态绑定。它们总是根据指针或引用的静态类型(即声明时的类型)来调用。
  • 虚函数(如 fun())在运行时会被动态绑定。它们会根据指针或引用实际指向的对象的类型来调用。
  • 仅在虚函数的顶层基类加上virtual关键字,子类不加,而改用override关键字

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

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

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

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

3.虚继承

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

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

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

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

相关文章

量化交易基础知识

目录 1 什么是量化交易2 谁可以成为一个量化交易员3 量化交易的优势与特点4 量化交易员的成长之路 1 什么是量化交易 量化交易也称算法交易&#xff0c;是一种严格按照计算机算法进行买卖证券决策的交易方式。更具体一点解释就是&#xff0c;量化交易利用数学模型、统计分析和计…

Ansys界面设计:ACT入门

目录 Introduction What is customization? What is extensibility? What is ACT? What capabilities does ACT provide? What skills are required for using ACT? How do I begin using ACT? Where can I find published ACT apps? Introduction 来自官方帮助…

软件开发故事 - 我对 CTO 撒谎并挽救了项目

原文&#xff1a;GrumpyOldDev - 2024.04.18 这是几年前的事情了。还记得在我职业生涯的初期&#xff0c;父亲曾告诉我&#xff0c;做好工作往往意味着要在上司的阻碍下做好需要做的事情。他的意思是&#xff0c;你可以让上司成功并感到快乐&#xff1b;也可以让上司做每一个决…

window10设置静态IP

右键桌面网络图标 点击属性 点击要查看的网络 点击详细信息 获得网络连接详细信息 右键WiFi符号 或者其他方式进入网络与internet中心 点击 WLAN 点击属性 点击编辑&#xff08;点击一个即可&#xff09; 选择手动将刚才的信息方进入即可 完成

20232801 2023-2024-2 《网络攻防实践》实践九报告

20232801 2023-2024-2 《网络攻防实践》实践九报告 1.实践内容 &#xff08;1&#xff09;手工修改可执行文件&#xff0c;改变程序执行流程&#xff0c;直接跳转到getShell函数。 &#xff08;2&#xff09;利用foo函数的Bof漏洞&#xff0c;构造一个攻击输入字符串&#xf…

差速机器人模型LQR 控制仿真(c++ opencv显示)

1 差速机器人状态方程构建 1.1差速机器人运动学模型 1.2模型线性化 1.3模型离散化 2离散LQR迭代计算 注意1&#xff1a;P值的初值为Q。见链接中的&#xff1a; 注意2&#xff1a;Q, R参数调节 注意3&#xff1a;LQR一般只做横向控制&#xff0c;不做纵向控制。LQR输出的速度…

视频号音乐怎么下载

音乐&#xff0c;那个能够触动灵魂的艺术形式&#xff0c;穿越屏幕&#xff0c;流淌在视频号的每一个角落。然而&#xff0c;有时候&#xff0c;我们更希望能将那些动人心弦的旋律保存下来&#xff0c;让它们成为我们日常生活的一部分&#xff0c;陪伴我们度过每一个动人瞬间。…

SAM轻量化应用Auto-SAM、Group-Mix SAM、RAP-SAM、STLM

1. Auto SAM&#xff08;Auto-Prompting SAM for Mobile Friendly 3D Medical Image Segmentation&#xff09; 1.1 面临问题 医学背景&#xff1a; &#xff08;1&#xff09;与自然图像相比&#xff0c;医学图像的尺寸更小&#xff0c;形状不规则&#xff0c;对比度更低。&…

【Qt 开发基础体系】QMap 类和 QHash 类以及 QVector 类

文章目录 1.QMap 详解1.1 QMap 的介绍1.2 QMap 的具体用法如下1.3 QmultiMap类 2.QHash 详解3. QMap 和 QHash 的对比4. QVector 详解 1.QMap 详解 1.1 QMap 的介绍 &#x1f427;① QMap<key,T>提供一个从类型为Key的键到类型为T的值的映射。通常&#xff0c;QMap存储的…

使用torch完成多卡训练

最近在学detr&#xff0c;顺便学了一下多卡训模型&#xff0c;它的源码写的非常不错&#xff01; 我自己在detr的代码的基础上实现了一个vae的训练&#xff0c;在mnist数据集上&#xff0c;4张2080上&#xff0c;batch size开到1024&#xff0c;训练快到飞起。 总结一下多卡训…

JUC下的CompletableFuture详解

详细介绍 CompletableFuture是Java 8引入的一个实现Future接口的类&#xff0c;它代表一个异步计算的结果。与传统的Future相比&#xff0c;CompletableFuture提供了更丰富的功能&#xff0c;比如链式调用、组合异步操作、转换结果、异常处理等&#xff0c;极大地增强了Java在…

力扣HOT100 - 739. 每日温度

解题思路&#xff1a; 单调栈 class Solution {public int[] dailyTemperatures(int[] temperatures) {int length temperatures.length;int[] ans new int[length];Deque<Integer> stack new LinkedList<>();for (int i 0; i < length; i) {int temperatu…

TCP超时重传机制

一、TCP超时重传机制简介 TCP超时重传机制是指当发送端发送数据后&#xff0c;如果在一定时间内未收到接收端的确认应答&#xff0c;则会认为数据丢失或损坏&#xff0c;从而触发重传机制。发送端会重新发送数据&#xff0c;并等待确认应答。如果在多次重传后仍未收到确认应答&…

VMware Workstation 17 Player 创建虚拟机教程

本教程是以windows server 2012物理机服务器安装好的VMware Workstation 17 Player为例进行演示&#xff0c;安装VMware Workstation 17 Player大家可以自行网上搜索安装。 1、新建虚拟机 双击安装好的VMvare图标&#xff0c;点击创建虚拟机。 2、选择是否安装系统 本步骤选…

复习了好久的软考中项,现在上半年不考了,该怎么办?

如果有更多学习时间的话&#xff0c;可以考虑报考高级职称&#xff0c;因为高级和中级职称的很多知识点有重叠&#xff0c;只需要再复习一下相关论文就可以了。 从2024年下半年开始&#xff0c;集成考试将采用最新版教材和大纲&#xff0c;与高级职称的新版教材内容相似度很高…

Spring框架学习笔记(二):Spring IOC容器配置 Bean,分别基于XML配置bean 和 基于注解配置 bean

1 Spring 配置/管理 bean 介绍 Bean 管理包括两方面 &#xff1a;创建 bean 对象&#xff1b;给 bean 注入属性 Bean 配置方式&#xff1a;基于 xml 文件配置方式&#xff1b;基于注解方式 2 基于 XML 配置 bean 2.1 通过类型来获取 bean 方法&#xff1a;给getBean传入一…

新型AI Stable Artisan横空出世?

StabilityAI宣布推出Stable Artisan 前言 就在今天&#xff0c;Stability AI宣布推出 Stable Artisan&#xff0c;让更广泛的受众能够使用 Stability AI 的 Developer Platform API 功能。Stable Artisan 具有他们的高级型号&#xff0c;例如 Stable Diffusion 3、Stable Video…

4000字超详解Linux权限

各位大佬好 &#xff0c;这里是阿川的博客 &#xff0c; 祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 在Linux当中权限的体现主要有两种 普通用户 超…

ARIMA模型在河流水质预测中的应用_含代码

#水质模型 #时间序列 #python应用 ARIMA 时间序列模型简介 时间序列是研究数据随时间变化而变化的一种算法&#xff0c;是一种预测性分析算法。它的基本出发点就是事物发展都有连续性&#xff0c;按照它本身固有的规律进行。ARIMA(p,d,q)模型全称为差分自回归移动平均模型 (A…

动态IP避坑指南:如何挑选合适的动态代理IP?

在如今的网络环境中&#xff0c;使用动态IP代理成为实现隐私保护、访问受限内容和提高网络效率的一种常见方式&#xff0c;选择合适的国外动态IP代理可以让我们的业务处理事半功倍。面对市面上琳琅满目的选择&#xff0c;如何挑选购买适合自己的动态IP代理服务呢&#xff1f;在…