首页 > 其他分享 >16.【CPP】详解继承

16.【CPP】详解继承

时间:2024-03-17 13:59:45浏览次数:18  
标签:组合 16 继承 成员 派生类 对象 详解 基类 CPP

继承方式

如图

在这里插入图片描述

注意点

1.基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它
2.基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的
3.使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式
4.在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里面使用,实际中扩展维护性不强

基类和派生类的赋值转换

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

int main()
{
	Student s;
	Person p = s;
	Person& rp = s;
	Person* pp = &s;
	return 0;
}

但是,基类对象不能赋值给派生类对象

继承中的作用域

  1. 在继承体系中基类和派生类都有独立的作用域。
    2.子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义(在子类成员函数中可以使用 基类::基类成员 显示访问)
    3.需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。
    4.注意在实际中在继承体系里面最好不要定义同名的成员。

派生类中的默认成员函数

构造

  1. 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。
    在这里插入图片描述
    注:Person(name)省略也会去调父类的默认构造

拷贝和赋值

  1. 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。派生类的operator=必须要调用基类的operator=完成基类的复制。
    在这里插入图片描述
    如果在声明时直接赋值,则不会调用赋值重载,而会调用拷贝构造
    在这里插入图片描述
int main()
{
	Student s1("猫哆", 10);
	Student s2(s1);
	Student s3;
	s3=s1;
	
	return 0;
}

上述代码才完成赋值
在这里插入图片描述

析构和构造的顺序

派生类对象初始化先调用基类构造再调派生类构造。 派生类对象析构清理先调用派生类析构再调基类的析构
在这里插入图片描述
因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同(这个我们后面会讲解)。那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系。

其他知识点

1.友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员。
2.基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例。
3.实现一个不能被继承的类:构造函数或析构函数私有

多继承

一个子类有两个或两个以上父类时称为多继承

菱形继承

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

虚继承解决问题

在这里插入图片描述
在这里插入图片描述
加上虚继承后

class A
{
protected:
	int _a;
};

class B :virtual public A
{
protected:
	int _b;
};

class C :virtual public A
{
protected:
	int _c;
};

class D :public B, public C
{
private:
	int _d;
};

在这里插入图片描述
20和12为B类和C类对A类的偏移量,_a只有一份,B类和C类通过偏移量找到a的位置,从而解决了数据冗余和二义性。
同一个类的不同对象存的偏移量地址都是一样的。
谁先被继承初始化列表就先初始化谁。

继承和组合

public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。
组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象。

优先使用对象组合,而不是类继承
继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,基类的内部细节对子类可见 。继承一定程度破坏了基类的封装,基类的改变,对派生类有很大的影响。派生类和基类间的依赖关系很强,耦合度高。
对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。
组合类之间没有很强的依赖关系,耦合度低。优先使用对象组合有助于你保持每个类被封装。实际尽量多去用组合。组合的耦合度低,代码维护性好。不过继承也有用武之地的,有些关系就适合继承那就用继承,另外要实现多态,也必须要继承。类之间的关系可以用继承,可以用组合,就用组合。

标签:组合,16,继承,成员,派生类,对象,详解,基类,CPP
From: https://blog.csdn.net/m0_73865858/article/details/136097883

相关文章

  • Java面试题:详解单例模式与内存泄漏?内存模型与volatile关键字的实操?并发工具包与并发框
    Java核心技术:设计模式、内存管理与并发编程深度解析在Java技术领域,设计模式、内存管理和并发编程是构建高效、稳定系统的关键。本文将通过三道综合性面试题,深入探讨这些核心知识点,帮助读者理解其背后的原理,并在实际编程中避免常见错误。面试题一:单例模式与内存泄漏问题核......
  • kmp算法next数组详解
             kmp算法是一项特别重要的算法,它的难点主要在于next数组的求解。##首先next[i]表示字符串下标i前子字符串(s[0~i-1])的最长相同前后缀的值。以字符串s="ababbacaba"为例子分析。前缀:aababaababababbababba ababbac ababbaca ababbacab后缀:aba......
  • 文心一言 VS 讯飞星火 VS chatgpt (216)-- 算法导论16.2 3题
    三、假定在0-1背包问题中,商品的重量递增序与价值递减序完全一样。设计一个高效算法求此背包问题的变形的最优解,证明你的算法是正确的。如果要写代码,请用go语言。文心一言:在0-1背包问题中,如果商品的重量递增序与价值递减序完全一样,那么我们可以利用这个特性设计一种高效的算法......
  • HDFSDATANODE数据传输详解
    本文主要阐述datanode中一个socket连接接收字节流的构成,帮助datanode的接收与处理数据。注意hadoop版本为3.1.1。写在前面Datanode本质上也是TCPServer,一般的TCPServer接到客户端请求以后会分配一个线程处理,对于Datanode而言,这个线程可以叫做Op处理连接。每个OP连接会多次和客户......
  • 二分/二分查找(整数二分详解+拓展浮点二分)
    先上题目在一个有序数组中,查找x所在的下标。输入第一行两个整数n和m。第二行n个数,表示有序的数列。接下来m行,每行一个整数x,表示一个询问的数。输出对于每个询问如果x在数列中,输出下标。否则输出-1样例输入15334579738输出141-1提示对于100%的数......
  • 【时事篇-05-03】20240316 一笔145元拆分成3笔存款存入(排除有相似性的十位数字)
    背景需求前文提到,每笔都存一样的数目,容易被银行识别违法,【时事篇-05-01】20240112150元存46只货币基金-CSDN博客文章浏览阅读580次,点赞15次,收藏11次。【时事篇-05-01】20240112150元存46只货币基金https://blog.csdn.net/reasonsummer/article/details/136106686前几天我......
  • 服务器端jupyter notebook映射到本地浏览器的操作【文章转自https://www.cnblogs.com/
    这篇文章转自主要介绍了服务器端jupyternotebook映射到本地浏览器的操作,做科研经常有这样的需求:即需要借助服务器的计算资源,本地编辑的工程文件需要每次都传到服务器才能运行。jupyter是较好的交互式编辑工具,有没有一种方式可以在jupyter上编辑属于服务器的文件呢?这就引出了我们......
  • 第五十七天| 647. 回文子串、5.最长回文子串、516.最长回文子序列
    Leetcode 647.回文子串题目链接:647回文子串题干:给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。回文字符串 是正着读和倒过来读一样的字符串。子字符串 是字符串中的由连续字符组成的一个序列。具有不同开始位置或结束位置的子串,即使是由相同的......
  • AI预测福彩3D第10弹【2024年3月16日预测--第2套算法重新开始计算第2次测试】
            今天继续开始咱们第2套算法的验证,计划每套算法连续测试10期,达到50%的命中率即为较优的模型,可继续使用。老规矩,先上图表,再下结论~                最终,经过研判分析,2024年3月16日福彩3D的七码预测结果如下:百位:1354798十位:324......
  • ic基础|时序篇06:输入约束set_input_delay与输出约束set_output_delay详解
    大家好,我是数字小熊饼干,一个练习时长两年半的ic打工人。我在两年前通过自学跨行社招加入了IC行业。现在我打算将这两年的工作经验和当初面试时最常问的一些问题进行总结,并通过汇总成文章的形式进行输出,相信无论你是在职的还是已经还准备入行,看过之后都会有有一些收获,如果看......