【C++】继承的基本特性(定义,赋值转换,友元,静态成员,虚拟继承,默认成员函数,作用域)

news2024/12/26 0:22:22

文章目录

  • 一、继承的定义
    • 1.定义格式
    • 2.继承基类成员访问方式的变化
  • 二、基类和派生类对象赋值转换
  • 三、继承的作用域
    • 1. 在继承体系中基类和派生类都有独立的作用域。
    • 2.子类和父类中有同名成员
    • 3.成员函数的隐藏
    • 4.注意在实际中在继承体系里面最好不要定义同名的成员。
  • 四、派生类的默认成员函数
  • 五、继承与友元
  • 六、继承与静态成员
  • 七、菱形虚拟继承
    • 1.菱形继承
    • 2.虚拟继承
    • 3.菱形虚拟继承原理:
      • 1.菱形继承的内存分布
      • 2.虚拟继承内存分布


一、继承的定义

它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。

1.定义格式

在这里插入图片描述
Person是父类,也称作基类。Student是子类,也称作派生类

2.继承基类成员访问方式的变化

在这里插入图片描述
总结:

  1. 基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在里面还是类外面都不能去访问它。
    在这里插入图片描述

  2. 基类private成员在派生类中是不能被访问, 如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。 可以看出保护成员限定符是因继承才出现的。

  3. 基类的私有成员在子类都是不可见, 基类的其他成员在子类的访问方式 == Min(成员在基类的访问限定符,继承方式),public > protected > private。

  4. 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。

  5. 在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用protetced/private继承

二、基类和派生类对象赋值转换

1.派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。这里有个形象的说法叫切片或者切割。寓意把派生类中父类那部分切来赋值过去。
2.基类对象不能赋值给派生类对象。
在这里插入图片描述
在这里插入图片描述

三、继承的作用域

1. 在继承体系中基类和派生类都有独立的作用域。

2.子类和父类中有同名成员

子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)
在这里插入图片描述

3.成员函数的隐藏

需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏
在这里插入图片描述

4.注意在实际中在继承体系里面最好不要定义同名的成员。

四、派生类的默认成员函数

基类(父类):

class Person {
public:
	Person(const char*name)
		:_name(name)
	{
		cout << "Person()" << endl;
	}
	Person(const Person& p)
		:_name(p._name)
	{
		cout << "Person(const Person&p)" << endl;
	}
 
	Person& operator=(const Person& p) {
		cout << "Person operator=(const Person& p)" << endl;
		if (this != &p) {
			_name = p._name;
		}
		return *this;
	}

	~Person() {
		cout << "~Person()" << endl;
	}
protected:
	string _name;
};

派生类(子类)

class Student :public Person {
public:
	Student(const char*name="张三", int id = 0)
		//派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。
		:Person(name)
		,_id(id)
	{}

	Student(const Student& s) 
		// 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
		:Person(s)//切割
		,_id(s._id)
	{}

	Student& operator=(const Student& s) {
		//派生类的operator = 必须要调用基类的operator = 完成基类的复制
		if (this != &s) {
			Person::operator=(s);//发生切割
			_id = s._id;
		}
		return *this;
	}
		~Student()
	{
		// 析构函数的函数名被
		// 特殊处理了,统一处理成destructor

		// 显示调用父类析构,无法保证先子后父
		// 所以子类析构函数完成就,自动调用父类析构,这样就保证了先子后父
		 
		//析构函数:先析构子类后析构父类
		//构造函数:先构造父类后构造子类
	}

protected:
	int _id;
};

运行结果:
在这里插入图片描述
总结:

  1. 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。
  2. 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
  3. 派生类的operator=必须要调用基类的operator=完成基类的复制。
  4. 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能
    保证派生类对象先清理派生类成员再清理基类成员的顺序。
  5. 派生类对象初始化先调用基类构造再调派生类构造。
  6. 派生类对象析构清理先调用派生类析构再调基类的析构。

在这里插入图片描述

五、继承与友元

友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员
在这里插入图片描述
想要正常运行需要派生类也加上友元才可以

六、继承与静态成员

基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例 。

在这里插入图片描述

七、菱形虚拟继承

1.菱形继承

在这里插入图片描述
菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。在Assistant的对象中Person成员会有两份。
在这里插入图片描述

2.虚拟继承

虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在Student和Teacher的继承Person时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要在其他地方去使用。
在这里插入图片描述

3.菱形虚拟继承原理:

class A
{
public:
 int _a;
};
// class B : public A
class B : virtual public A
{
public:
 int _b;
};
// class C : public A
class C : virtual public A
{
public:
 int _c;
};
class D : public B, public C
{
public:
 int _d;
};
int main()
{
 D d;
 d.B::_a = 1;
 d.C::_a = 2;
 d._b = 3;
 d._c = 4;
 d._d = 5;
 return 0;
}

1.菱形继承的内存分布

下图是菱形继承的内存对象成员模型:这里可以看到数据冗余
在这里插入图片描述

2.虚拟继承内存分布

下图是菱形虚拟继承的内存对象成员模型:这里可以分析出D对象中将A放到的了对象组成的最下面,这个A同时属于B和C,那么B和C如何去找到公共的A呢?这里是通过了B和C的两个指针,指向的一张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到下面的A。
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

【C语言学习】整数类型表达数的范围

一、整数类型表达数的范围 1.char类型 char 是1个字节 &#xff0c;即00000000 ~ 11111111&#xff0c;一般情况默认是有符号char(signed char) ,此时char所能表达的数就是 -128 ~ 127&#xff0c;即 -2 ^ n-1 ~ (2 ^ n-1)-1 ,其中n是位数或比特位&#xff08;1字节8位8比特&…

OPENCV C++(四)形态学操作+连通域统计

形态学操作 先得到一个卷积核 Mat kernel getStructuringElement(MORPH_RECT,Size(5,5)); 第一个是形状 第二个是卷积核大小 依次为腐蚀 膨胀 开运算 闭运算 Mat erodemat,dilatemat,openmat,closemat;morphologyEx(result1, erodemat, MORPH_ERODE, kernel);morphologyEx…

万界星空科技/免费开源MES系统/免费仓库管理

仓库管理&#xff08;仓储管理&#xff09;&#xff0c;指对仓库及仓库内部的物资进行收发、结存等有效控制和管理&#xff0c;确保仓储货物的完好无损&#xff0c;保证生产经营活动的正常进行&#xff0c;在此基础上对货物进行分类记录&#xff0c;通过报表分析展示仓库状态、…

道本科技受邀参加建筑产业互联网推动建筑产业现代化体系构建座谈会,以数字化产品为建筑行业注入新动能!

2023年7月底&#xff0c;道本科技作为中国建筑业协会合作伙伴&#xff0c;受邀参加了建筑产业互联网推动建筑产业现代化体系构建座谈会。在这次座谈会上&#xff0c;道本科技旗下产品“合规数”“合同智能审查”和“智合同范本库”被中国建筑&#xff08;中小企业&#xff09;产…

Leaflet.Control.Opacity 控制图层的透明度

最新有一个需求&#xff0c;能动态的控制Leaflet.js 地图图层的透明度&#xff0c;官网文档: https://leafletjs.com/reference.html#gridlayer-setopacity 一直有个setOpacity方法&#xff0c;我以为拿来就能使呢&#xff0c;其实不行。后来找到一个日本人开发的demo: 右侧Co…

部署SpringBoot项目在服务器上,并通过swagger登录

1.项目编译打包 2.上传jar包到服务器并启动 xftp将打包好后的jar包传到虚拟机指定路径 java -jar执行该jar包 3.通过swagger登录 输入后点击下面的执行按钮 会得到一个tocken 4.将tocken放到postman的Headers中 5.修改url 例如我本地测试是http://localhost:8080/接口名&am…

关于Java的未来探讨,看看国外开发者怎么说的

博主在浏览 medium 社区时&#xff0c;发现了一篇点赞量 1.5k 的文章&#xff0c;名称叫《Java is Dead — 5 Misconceptions of developers that still think Java is relevant today!》直译过来就是《Java 已死 — 开发人员对 Java 在现代编程语言中的5个误解》。这篇文章可以…

层叠上下文

一、层叠上下文 在CSS2.1规范中&#xff0c;每个盒模型的位置是三维的&#xff0c;分别是平面画布上的x轴&#xff0c;y轴以及表示层叠的z轴&#xff0c;层叠上下文即元素在某个层级上z轴方向的排列关系。假定用户正面向&#xff08;浏览器&#xff09;视窗或网页&#xff0c;…

合并pdf怎么合并?试试这几种方法

合并pdf怎么合并&#xff1f;合并PDF文件是处理PDF文件时最基本的需求之一。在日常工作和生活中&#xff0c;我们可能需要将多个PDF文件合并成一个文件&#xff0c;以方便管理、浏览和分享。下面就给大家介绍几种PDF合并的方法。 首先&#xff0c;让我们介绍一下【迅捷PDF转换器…

项目中引用svg图标,公共组件SvgIcon使用,注册全局组件,使用自定义插件注册全局组件

在开发项目的时候经常会用到svg矢量图,而且我们使用SVG以后&#xff0c;页面上加载的不再是图片资源, 这对页面性能来说是个很大的提升&#xff0c;而且我们SVG文件比img要小的很多&#xff0c;放在项目中几乎不占用资源。 1、安装依赖插件 pnpm install vite-plugin-svg-ic…

API是什么?

API是什么&#xff1f; API&#xff08;Application Programming Interface,应用程序编程接口&#xff09;是一些预先定义的函数&#xff0c;目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力&#xff0c;而又无需访问源码&#xff0c;或理解内部工作机制…

SAP BAPI BAPI_SALESDOCUMENT_COPY 直接实现VA01复制销售合同创建小搜订单

BAPI :BAPI_SALESDOCUMENT_COPY 输入参数 &#xff1a; 销售合同、订单类型 输出参数&#xff1a;生成的销售订单号 实现的操作:

自动分班软件:一分钟制作分班查询系统,这个工具轻松实现

作为一名老师&#xff0c;在即将到来的新学期&#xff0c;我们需要进行学生的分班工作&#xff0c;而分班查询系统可以帮助我们更加高效地完成这项工作。在这篇文章中&#xff0c;我将向大家介绍如何创建一个分班查询系统。 首先&#xff0c;我们需要确定分班查询系统的需求和…

java八股文补充

1、JAVA BIO、NIO、AIO的区别 BIO &#xff08;Blocking I/O&#xff09;&#xff1a;同步阻塞I/O模式。当有其他线程进行数据读写时阻塞等待。当用户线程发出IO请求之后&#xff0c;内核会去查看数据是否就绪&#xff0c;如果没有就绪就会等待&#xff0c;用户线程就会处于阻…

Linux下多python版本共存

python下载官网 https://www.python.org/downloads/ python支持多版本共存&#xff0c;是大版本共存&#xff0c;小版本不共存。 python3.6 和 3.7 共存python3.6.6和python3.6.8 不共存 1.下载特定版本的python 进入官网后点击Downloads–>All releases点击‘Gzipped s…

在职读研想要成功上岸,社科院杜兰大学金融管理硕士机不可失

近年来&#xff0c;中国考研报名人数节节攀升&#xff0c;2023年考研报名人数达到了474万。在如此庞大的考生群体中&#xff0c;成功被录取的人数却不足两成&#xff0c;这一数字引起了社会各界广泛的热议和关注。招生规模如此浩大&#xff0c;录取率却如此之低。其实考研录取率…

【2023年电赛国一必备】C题报告模板--可直接使用

任务 图1 任务内容 要求 图2 基本要求内容 图3 发挥部分内容 说明 图4 说明内容 评分标准 图5 评分内容 正文 &#xff08;部分&#xff09; 摘要 本实验基于TI公司的TM4C123GH6PM主控&#xff0c;结合OPA2337芯片和其他硬件模块&#xff0c;设计并制作了一种单相逆变器…

如何快速完成 App 安全评估报告【最快当天完事】

文章目录 1. App下架展示2. 检查App是否存在问题3. 注册《安全评估》 信息4. 人工快速干预&#xff0c;加快审核步骤5. 面审阶段6. 后续 1. App下架展示 在华为应用市场上架的App突然间被下架&#xff0c;把我搞得猝不及防&#xff0c;原因如下&#xff1a; 是因为我们缺少 《…

提升项目管理效率的优秀软件推荐

Zoho Projects项目管理软件拥有随需而配的强大项目功能&#xff0c;帮助项目经理实现整体项目把控。系统以“动态管理、实时共享”的先进理论实现项目进度、成本、资源、绩效、风险等的有效跟进&#xff0c;解决项目管理中因信息滞后导致的项目失败问题&#xff0c;提升企业项目…

2.虚拟机开启kali_linux

首先你应该搞一个虚拟机&#xff0c;搞虚拟机可以看一下这个 附录三 虚拟机的使用_Suyuoa的博客-CSDN博客 然后你需要搞一个 kali linux的镜像 Get Kali | Kali Linux 镜像下载好之后解压&#xff0c;你会得到一个文件夹包含下面这些文件 之后打开VMware&#xff0c;点击打开虚…