IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++中的继承 -> 正文阅读

[C++知识库]C++中的继承

继承的概念和定义

继承的概念

继承是面向对象程序设计使代码可以复用的重要手段,当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。

继承的定义

定义格式

在这里插入图片描述

继承父类成员访问关系的变化

类成员/继承方式public继承protected继承private继承
基类的public成员派生类的public成员派生类的private成员派生类的private成员
基类的protect成员派生类的protected成员派生类的protected成员派生类的private成员
基类的private成员派生类中不可见派生类中不可见派生类中不可见

父类和子类的对象赋值转换

  1. 子类对象可以赋值给父类的对象/父类的指针/父类的引用。一般情况下子类对象都比父类对象大,这里赋值的时候会产生切片或者叫切割。
    切片/切割
    在这里插入图片描述

  2. 父类对象不能赋值给子类对象。但是指针和引用可以,但是必须进行强制类型转换,并且这个行为十分危险,可能存在越界访问。

class Person
{
public:
	string _name;
};
class Student:public Person
{
public:
	int _age;
	int _major;
};

int main()
{
	//子类可以赋值给父类
	Student a;
	Person b = a;
	Person* c = &a;
	Person& b = a;
	//父类不能赋值给子类
	a = b;
	//父类不能赋值给子类,但是可以进行强制转换
	Person* b1 = &b;
	Student* a1 = (Student*)b1;
	return 0;
}

继承中的作用域

  1. 在继承体系中父类和子类都有自己独立的作用域
  2. 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)

子类的默认成员函数

默认成员函数

  1. 构造函数
  2. 析构函数
  3. 拷贝构造函数
  4. 赋值操作

原则

继承下来的调用父类处理,子类的按照普通类的基本规则。
那么什么情况下需要我们自己写?

  1. 父类没有默认构造,需要我们自己写默认构造
  2. 若子类没有资源需要释放,就需要我们自己显示的写析构函数
  3. 若子类存在深浅拷贝问题,就需要实现拷贝构造和赋值解决深浅拷贝问题
    如何写?
    父类成员调用父类对应的构造,拷贝构造,operator=和析构处理,自己成员按照普通类处理。
    析构函数的名称会被统一处理为destructor()
  4. 子类的析构函数和父类的析构函数会构成隐藏
  5. 子类的析构函数结束时会自动调用父类的析构函数
  6. 子类的析构函数不需要调用父类的析构函函数它会自动调用,这样才能保证先析构子类成员,再析构父类成员。

继承与友元

友元关系不能继承,就比如父亲的朋友不一定是你的朋友。

继承与静态成员

父类定义了static成员,则整个继承体系中只有一个这样的静态成员,无论派生出多少个子类,都只有一个static成员,因此静态成员可以继承下来,但是只有一份。

菱形继承以及菱形虚拟继承

单继承

一个子类只有一个直接父类时称这个继承关系为单继承。

多继承

一个子类有两个或者两个以上的直接父类时称这个继承关系为多继承。

菱形继承

菱形继承是多继承的一种特殊情况
在这里插入图片描述
当这样的继承关系出现的时候,对于Assistant会形成数据的冗余以及二义性,因为在其中出现了两份Person。
在这里插入图片描述
我们看下面一串代码,

在非虚继承中

#include<iostream>
using namespace std;

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;
}

在这里插入图片描述
当我们查看d对象的地址,我们看到里面的存储是这样子存储的。并且是先继承谁先存储谁,倘若我们将代码中的D类换为

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

在这里插入图片描述
我们要是将继承的顺序进行调换,那么我们将看到在d对象中就先存谁的顺序就会变换,先继承的先进行存储。

在虚继承中

当我们进行调试

  1. 首先创建了D对象在这里插入图片描述
  2. _a出现在这个位置在这里插入图片描述
  3. C中的_a将之前B中的_a进行了覆盖在这里插入图片描述
  4. 当我i们再观察内存发现_a存在一个公共的区域
    在这里插入图片描述
    我们发现当我们进行虚继承时是这样子进行存储的,A处在一个公共的区域,但是BC前面的东西还并不知道是什么
    在这里插入图片描述
    我们查看这里的地址,
    在这里插入图片描述
    发现这个地址里面记录着一个数字,这个数字就是B和C相对于公共成员A的偏移量/相对距离。
    此时这个A类一般称为虚基类,因为是虚继承下来的,在D里面,A存放在一个公共的区域,可能B,C都需要进行寻找A,这时候就通过虚基表中记录的偏移量来进行查找,这个BC之前的这个值就为虚基表的地址,虚基表中存储的就是偏移量,偏移量上面还有一个空间,既然为虚基表,表里面不会只存一个值,至于这个值具体是什么,在后面的多态进行讲。

继承和组合

  1. public继承是一种is-a的关系,也就是说每个子类对象都是一个父类对象。
  2. 组合是一种has-a的关系,假设B组合了A,那么每个B对象中都有一个A对象
  3. 优先使用组合而不是类继承。
    在这里插入图片描述
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-12-25 10:47:31  更:2022-12-25 10:48:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 4:48:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码