C++继承的基本意义

文章目录

    • 一、继承的本质和原理
    • 二、重载、隐藏和覆盖
    • 三、基类与派生类的转换

一、继承的本质和原理

继承的本质:a. 代码的复用 b.
类和类之间的关系:
组合:a part of… 一部分的关系
继承:a kind of… 一种的关系
在这里插入图片描述
总结:

  1. 外部只能访问对象public的成员,protected和private的成员无法直接访问。
  2. 在继承结构中,派生类从基类可以继承过来private的成员,但是派生类却无法直接访问。
  3. protected和private的区别?
    在基类中定义的成员,想被派生类访问,但是不想被外部访问,那么在基类中,把相关成员定义成protected保护的;
    如果派生类和外部都不打算访问,那么在基类中,就把相关成员定义成private私有的。
  4. 默认的继承方式是什么?
    要看派生类是用class定义的,还是struct定义的。
    class定义派生类,默认继承方式就是private私有的。
    struct定义派生类,默认继承方式就是public私有的。
  5. 派生类从继承可以继承来所有的成员(变量和方法),除过构造函数和析构函数
  6. 派生类怎么初始化从基类继承来的成员变量呢?答:通过调用基类相应的构造函数来初始化。
  7. 派生类的构造函数和析构函数,负责初始化和清理派生类部分
    派生类从基类继承来的成员的初始化和清理由谁负责呢?是由基类的构造和析构函数来负责。
  8. 派生类对象构造和析构的过程是:
    1.派生类调用基类的构造函数,初始化从基类继承来的成员;
    2.调用派生类自己的构造函数,初始化派生类自己特有的成员;
    …派生类对象的作用域到期了
    3.调用派生类的析构函数,释放派生类成员可能占用的外部资源(堆内存,文件);
    4.调用基类的析构函数,释放派生类内存中,从基类继承来的成员可能占用的外部资源(堆内存,文件)。
#include <iostream>
using namespace std;

class Base {
public:
	Base(int data)
		: ma(data) 
	{
		cout << "Base()" << endl;
	}

	~Base() {
		cout << "~Base()" << endl;
	}
protected:
	int ma;
};

class Derive : public Base {
public:
	Derive(int data)
	//: ma(data) //"Base":没有合适的默认构造函数可用
	: Base(data)
	, mb(data)
	{
		cout << "Derive()" << endl;
	}
	~Derive() {
		cout << "~Derive()" << endl;
	}
private:
	int mb;
};

int main() {
	Derive d(20);
	return 0;
}

二、重载、隐藏和覆盖

  1. 重载关系
    一组函数要重载,必须处在同一个作用域当中;而且函数名字相同,参数列表不同。
  2. 隐藏(作用域的隐藏)的关系
    在继承结构当中,派生类的同名成员,把基类的同名成员给隐藏调用了。
  3. 覆盖
    基类和派生类的方法,返回值、函数名以及参数列表都相同,而且基类的方法是虚函数,那么派生类的方法就自动处理成虚函数,它们之间成为覆盖关系。
#include <iostream>
using namespace std;

class Base {
public:
	Base(int data)
		: ma(data) 
	{
		cout << "Base()" << endl;
	}

	~Base() {
		cout << "~Base()" << endl;
	}

	void show() { cout << "Base::show()" << endl; }
	void show(int) { cout << "Base::show(int)" << endl; }
protected:
	int ma;
};

class Derive : public Base {
public:
	//"Base":没有合适的默认构造函数可用
	Derive(int data = 20)
	: Base(data)
	, mb(data)
	{
		cout << "Derive()" << endl;
	}
	~Derive() {
		cout << "~Derive()" << endl;
	}
	void show() { cout << "Base::show()" << endl; }
private:
	int mb;
};

int main() {
	Derive d;
	d.show();
	// 优先找的是派生类自己作用域的show名字成员; 没有的话,才去基类里找
	d.show(10); //"Derive::show": 函数不接受 1 个参数

	return 0;
}

三、基类与派生类的转换

把继承结构,也说成从上(基类)到下(派生类)的结构。

#include <iostream>
using namespace std;

class Base {
public:
	Base(int data = 10)
		: ma(data) 
	{
		cout << "Base()" << endl;
	}

	~Base() {
		cout << "~Base()" << endl;
	}

	void show() { cout << "Base::show()" << endl; }
	void show(int) { cout << "Base::show(int)" << endl; }
protected:
	int ma;
};

class Derive : public Base {
public:
	//"Base":没有合适的默认构造函数可用
	Derive(int data = 20)
	: Base(data)
	, mb(data)
	{
		cout << "Derive()" << endl;
	}
	~Derive() {
		cout << "~Derive()" << endl;
	}
	void show() { cout << "Base::show()" << endl; }
private:
	int mb;
};

int main() {
	Base b(10);
	Derive d(20);

	// 基类对象b <- 派生类对象d     类型从下到上的转换  Y
	b = d;
	
	// 派生类对象d <- 基类对象b     类型从上到下的转换  N
	// d = b;

	// 基类指针(引用) <- 派生类对象 类型从下到上的转换  Y
	Base *pb = &d;
	pb->show();   // 只能访问基类部分Base::show()     ((Derive*)pb)->show();
	pb->show(10); // 只能访问基类部分Base::show(int)

	// 派生类指针(引用) <- 基类对象 类型从上到下的转换  N
	// Derive *pd = &b; // Derive *pd = (Derive*)&b; 类型强转不安全,涉及了内存的非法访问!

	return 0;
}

总结:在继承结构中进行上下的类型转换,默认只支持从下到上的类型的转换OK

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

简单易懂的倒排索引详解

文章目录 简单易懂的倒排索引详解一、引言 简单易懂的倒排索引详解二、倒排索引的基本结构三、倒排索引的构建过程四、使用示例1、Mapper函数2、Reducer函数 五、总结 简单易懂的倒排索引详解 一、引言 倒排索引是一种广泛应用于搜索引擎和大数据处理中的数据结构&#xff0c;…

FinRobot:一个使用大型语言模型的金融应用开源AI代理平台

“FinRobot: An Open-Source AI Agent Platform for Financial Applications using Large Language Models” 论文地址&#xff1a;https://arxiv.org/pdf/2405.14767 Github地址&#xff1a;https://github.com/AI4Finance-Foundation/FinRobot 摘要 在金融领域与AI社区间&a…

Docker使用指南(一)——镜像相关操作详解(实战案例教学,适合小白跟学)

目录 1.镜像名的组成 2.镜像操作相关命令 镜像常用命令总结&#xff1a; 1. docker images 2. docker rmi 3. docker pull 4. docker push 5. docker save 6. docker load 7. docker tag 8. docker build 9. docker history 10. docker inspect 11. docker prune…

Qt跨屏窗口的一个Bug及解决方案

如果我们希望一个窗口覆盖用户的整个桌面&#xff0c;此时就要考虑用户有多个屏幕的场景&#xff08;此窗口要横跨多个屏幕&#xff09;&#xff0c;由于每个屏幕的分辨率和缩放比例可能是不同的&#xff0c;Qt底层在为此窗口设置缩放比例&#xff08;DevicePixelRatio&#xf…

Linux 传输层协议 UDP 和 TCP

UDP 协议 UDP 协议端格式 16 位 UDP 长度, 表示整个数据报(UDP 首部UDP 数据)的最大长度如果校验和出错, 就会直接丢弃 UDP 的特点 UDP 传输的过程类似于寄信 . 无连接: 知道对端的 IP 和端口号就直接进行传输, 不需要建立连接不可靠: 没有确认机制, 没有重传机制; 如果因…

安全实验作业

一 拓扑图 二 要求 1、R4为ISP&#xff0c;其上只能配置IP地址&#xff1b;R4与其他所有直连设备间均使用共有IP 2、R3-R5-R6-R7为MGRE环境&#xff0c;R3为中心站点&#xff1b; 3、整个OSPF环境IP基于172.16.0.0/16划分&#xff1b; 4、所有设备均可访问R4的环回&#x…

防御保护:安全策略配置

目录 一、实验拓扑 二、实验要求 ​编辑 三、要求分析 四、实验配置 前置配置 1.配置vlan与access、truck接口 2.进入web界面进行配置 3.安全策略的配置 3.1实现实验需求2(办公区PC在工作日时间(周一至周五,早8晚6)可以正常访问OA Server,其他时间不允许) 新建地址…

第一个Qt开发实例(一个Push Button按钮和两个Label)【包括如何在QtCreator中创建新工程、代码详解、编译、环境变量配置、测试程序运行等】

目录 Qt开发环境QtCreator的安装、配置在QtCreator中创建新工程在Forms→mainwindow.ui中拖曳出我们要的图形按钮查看拖曳出按钮后的代码为pushButton这个图形添加回调函数编译工程关闭开发板上QT的GUI(选做)禁止LCD黑屏(选做)设置Qt运行的环境变量运行Qt程序如何让程序在系统启…

【含文档+PPT+源码】基于大数据的交通流量预测系统

项目介绍 本课程演示的是一款基于Python的图书管理系统的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 带你从零开始部署运行本套系统 该项目附…

第二十三章 MySQL锁之表锁

目录 一、概述 二、语法 三、特点 一、概述 表级锁&#xff0c;每次操作锁住整张表。锁定粒度大&#xff0c;发生锁冲突的概率最高&#xff0c;并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中。 对于表级锁&#xff0c;主要分为以下三类&#xff1a; 1. 表锁 2. 元数…

在Vue3 + Vite 项目中使用 Tailwind CSS 4.0

文章目录 首先是我的package.json根据官网步骤VS Code安装插件验证是否引入成功参考资料 首先是我的package.json {"name": "aplumweb","private": true,"version": "0.0.0","type": "module","s…

Unity安装教学与相关问题

文章目录 1. 前言2.Unity Hub2.1 下载Unity Hub2.2 安装Unity Hub2.3 注册Unity账号2.4 在Hub上登录账号2.5 在Hub上获取许可证 3. 下载并安装Unity3.1 从Unity Hub下载&#xff08;推荐&#xff09;3.1.1 选择下载版本3.1.2 选择下载组件3.1.3 安装Visual Studio Community 20…

分层模型和应用协议

网络分层模型和应用协议 分层模型 五层网络模型 面对复杂的问题&#xff0c;可以使用分层的方式来简化。 经过不断的演化&#xff0c;网络最终形成了五层模型&#xff1a; 数据的传输 四层、五层、七层 应用层协议 URL URL&#xff08;uniform resource locator&#xff…

Qt常用控件 多元素控件

文章目录 1. QListWidget1.1 常用属性和方法1.2 常用信号1.4 例子1&#xff0c;操作元素 2. QTableWidget2.1 常用属性和方法2.2 常用信号2.3 例子1&#xff0c;创建表格3.1 常用属性和方法3.2 常用信号3.3 例子1&#xff0c;创建树形结构 Qt中提供的多元素控件有: QListWidget…

基于RTOS的STM32游戏机

1.游戏机的主要功能 所有游戏都来着B站JL单片机博主开源 这款游戏机具备存档与继续游戏功能&#xff0c;允许玩家在任何时候退出当前游戏并保存进度&#xff0c;以便日后随时并继续之前的冒险。不仅如此&#xff0c;游戏机还支持多任务处理&#xff0c;玩家可以在退出当前游戏…

动态获取脚本名称作为日志文件的名称

优点 独立性&#xff1a; 每个脚本的日志独立存储&#xff0c;避免日志混杂&#xff0c;便于排查问题。 灵活性&#xff1a; 支持动态获取脚本名称&#xff0c;无需手动指定日志记录器名称。 可扩展性&#xff1a; 可以轻松扩展日志格式、级别、存储路径等功能。 易用性&…

站在JavaScript的视角去看,HTML的DOM和GLTF的Json数据。

很多前端小伙伴没有见过、操作过gltf文件&#xff0c;对非常懵逼&#xff0c;本文从前端小伙伴最熟悉的dom模型为切入口&#xff0c;以类别的方式来学习一下gltf文件。 一、结构与组织形式 HTML DOM&#xff08;文档对象模型&#xff09;&#xff1a; 树形结构&#xff1a;HT…

字节序与Socket编程

字节序 字节序分为大端字节序(Big-Endian) 和小端字节序(Little-Endian)。大端字节序是指一个整 数的最高位字节(23 ~ 31 bit)存储在内存的低地址处,低位字节(0 ~ 7 bit)存储在内存的高地址处;小端字节序则是指整数的高位字节存储在内存的高地址处,而低位字节则存储…

Verilog基础(三):过程

过程(Procedures) - Always块 – 组合逻辑 (Always blocks – Combinational) 由于数字电路是由电线相连的逻辑门组成的&#xff0c;所以任何电路都可以表示为模块和赋值语句的某种组合. 然而&#xff0c;有时这不是描述电路最方便的方法. 两种always block是十分有用的&am…

[mmdetection]fast-rcnn模型训练自己的数据集的详细教程

本篇博客是由本人亲自调试成功后的学习笔记。使用了mmdetection项目包进行fast-rcnn模型的训练&#xff0c;数据集是自制图像数据。废话不多说&#xff0c;下面进入训练步骤教程。 注&#xff1a;本人使用linux服务器进行展示&#xff0c;Windows环境大差不差。另外&#xff0…