继承的基本知识
概念
假设基于A类,创建了B类,那么称A为B的父类,B为A的子类
子类会继承父类的成员变量及成员函数,但是不能继承构造、析构、运算符重载
假设又基于B创建了C,那么称B为C的直接基类,A为C的间接基类
继承按照字面意思就是继承,而不是包含,当然了在代码中,如果两个类只包含关系,也可以这么写,但是不建议。比如人继承了生物,人包含了生物的属性和方法,同样人包含了脑袋,但是不建议说人继承了脑袋。同样一粒米属于米类,即使一粒米长了翅膀,它也是米的一种,它是由米演变而来的,它继承了米的所有属性及方法,也演变了自己的属性和方法。
语法
class A
{
public:int time;
}
class B:public A
{
public:int x;int y;
}
class C:public B
{int hp;
}
这里B继承了A,C继承了B,C包括了A和B的所有成员属性及函数,B只包括了 A的属性及函数
这里如果继承语法里面的public不写,不写就相当于private
protected使用时机
当继承父类时,父类的private成员不能被子类访问,但是父类的private成员在子类的内存中还是存在,只是不能访问,而protected属性和private没有区别,唯一区别是在继承后,它的子类可以访问父类的protected成员
final关键字
当加上关键字后,这个类就不能被继承
public、protected等继承的区别
继承方式为public,则父类中的public成员被继承为public,protected被继承为protected,父类中的private被继承不可访问
继承方式为protected,则父类中的pulic成员被继承为protected,protected被继承为protected,private被继承不可以访问
继承方式为private,父类中的public和protected被继承为private,private成员被继承不可访问
如果我们想要修改子类继承父类的成员权限时,可以用using 父类::成员
class A
{
protected:int x;int y;
};
class B :public A
{
public:using A::x;
};
int main()
{B b;b.x = 100;A a;a.x = 200;
}
比如这样,就修改了x在B中的权限,但是这段代码还是不能运行,因为x在A中,还是以proteced的特征存在
构造函数和继承
#include <iostream>
class Object
{
protected:char Name[5]{};
public:Object(){std::cout << "Object is created" << std::endl;}
};
class seeObject:protected Object
{
public:int x;seeObject(){std::cout << "seeObject is created" << std::endl;}
};
int main()
{seeObject stone;system("pause");
}
这里当实例化seeobject对象 stone时,会同时调用父类的构造函数,因为在子类中继承了父类的成员变量,所以实例化也要实现这个成员变量,从而调用默认构造,构造顺序是父类构造、子类构造,因为在seeobject类的内存中,父类的成员在前面。
#include <iostream>
class Object
{
protected:char Name[5]{};
public:Object(){std::cout << "Object is created" << std::endl;}Object(const Object& obj){std::cout << "Object copy is created" << std::endl;}
};
class seeObject:protected Object
{
public:int x;seeObject(){std::cout << "seeObject is created" << std::endl;}seeObject(const seeObject& seeobj){std::cout << "seeObject copy is created" << std::endl;}
};
class creature:protected seeObject
{
protected:int hp;
public:creature(){x = 3200;std::cout << "creature is created" << std::endl;}creature(const creature& cret){std::cout << "creature copy is created" << std::endl;}
};
int main()
{creature monkey;creature monkey2 = monkey;system("pause");
}
这里,子类进行复制构造时,不会调用父类的复制构造函数,子类实例化时都是调用父类的默认构造函数,不会调用其他构造,比如不会调用父类的复制构造,除非显示指定
为什么呢?
当进行复制构造的时候,按理说人类拥有了动物类的所有成员变量,当进行人类的对象复制构造时,那这个时候会调用人类的复制构造函数,动物类的复制构造会不会被调用呢?如果说人类实例化对象也属于动物类的话,那么动物类的复制构造也会被调用,
按照语法规定,不会调用动物类的复制构造,只会调用动物类的构造函数
=========================================================================
为什么会调用动物的普通构造呢?直接一点,直接调用人的复制构造不就好了吗?直接一次性全部打包复制,这是因为人的继承属性,属性必须初始化,而这个属性是属于动物类的,就会默认调用动物的默认构造进行初始化,人不会继承动物的默认构造,但是会调用它
==============================================================================
为什么不调用动物的复制构造呢?就好比,动物有血有肉,人有血有肉,动物的血肉值为100,人的血肉值为200,当复制人的时候,肯定是复制200的血肉值,所以肯定不是调用动物的复制构造,不然血肉值也成了100,只需要把人的继承属性调用动物的普通构造初始化,再加上人的特有属性,两个加起来再调用复制构造复制过去即可。
=========================================================================
为什么不调用人的普通构造呢?因为既然要复制一个人,所以就肯定会调用复制构造,当给人进行普通构造的时候,就好比,初始化一个人的血肉值为10,然后实例化后,将人的血肉值设置为200,那么当复制这个人的时候,肯定不会再调用这个人的普通构造,因为这样又将他设置成了10。所以调用了复制构造肯定不会再调用普通构造
=========================================================================
那么问题来了,按照前面所说,调用了动物的普通构造,将血肉值初识化成了100,只调用人的复制构造,不调用人的普通构造,那么在进行复制的时候,会不会把100也给复制过去呢?不会的,因为在创建这个要复制的对象时,已经给它进行了初始化血肉值为200,就好比要复制一块金子,这块金子早就已经点石成金了,不用担心复制一块石头过去。
=========================================================================
#include <iostream>
class seeObject
{
public:int x;seeObject(){std::cout << "seeObject is created" << std::endl;}seeObject(const seeObject& seeobj){std::cout << "seeObject copy is created" << std::endl;}seeObject(int val) :x{ val }{ }
};
class creature:protected seeObject
{
protected:int hp;
public:/using seeObject::seeObject;creature():seeObject {100},hp{200}{x = 3200;std::cout << "creature is created" << std::endl;}creature(const creature& cret):seeObject{cret}{std::cout << "creature copy is created" << std::endl;}
};
int main()
{creature monkey;creature monkey2 = monkey;system("pause");
}
这里,采用成员初始化列表的方式,将100传入seeObject(int val),注意,这里的x=3200,只能写在括号里面,而不能用初始化列表的方式,因为这里还未完成构造
当子类委托构造父类的复制构造函数时,传入的参数是子类类型,也可以,因为子类实例化对象类型也属于父类对象类型,比如人属于动物类,虽然子类多了自己的属性和方法,但它仍然符合父类的定义
==================================
知识扩展*:<1>.通常来说,子类肯定含有父类所有的成员变量和方法函数.所以用父类指针指向子类时,没有问题,因为父类有的,子类都有,不会出现非法访问问题.
<2>.如果用子类指针指向父类的话,一旦访问子类特有的方法函数或者成员变量(基类是没有的),就会出现非法访问;
因为被子类指针指向的由父类创建的对象,根本没有要访问的那些内容,那些是子类特有的,只有用子类初始化对象时才会有
===================================
对于第23行,using seeObject::seeObject;这句代码是继承父类的有参构造函数,使用using继承构造函数是不能继承默认构造和副本构造,其他都可以继承,比如有参构造。继承下来的构造函数不改变它的属性,如果在父类中,它是public,那么继承后,如果把using seeObject::seeObject;这段代码放入creature的private中,它也是public属性。
继承构造时不能选择继承哪个有参构造,而是将所有有参构造全部继承下来
继承和析构
析构的顺序和构造相反,最先析构的是子类,然后才是父类,因为子类对父类有依赖,所以要先析构子类。当把子类中的原有成员销毁时,调用子类的析构,然后销毁继承的成员时,又会调用父类的析构
相关文章:
继承的基本知识
概念 假设基于A类,创建了B类,那么称A为B的父类,B为A的子类 子类会继承父类的成员变量及成员函数,但是不能继承构造、析构、运算符重载 假设又基于B创建了C,那么称B为C的直接基类,A为C的间接基类 继承按…...
【Frida-实战】EA游戏平台的文件监控(PsExec.exe提权)
▒ 目录 ▒ 🛫 问题描述环境 1️⃣ 代码编写开源代码搜索自己撸代码procexp确定句柄对应的文件名并过滤 2️⃣ PsExec.exe提权定位找不到EABackgroundService.exe的问题 PsExec.exe提权PsExec.exe原理 🛬 结论📖 参考资料 🛫 问题…...
可视化和回归分析星巴克咖啡在中国的定价建议
可视化和回归分析星巴克咖啡在中国的定价建议。星巴克的拿铁大杯Tall 在各国的价格。 Claude AI | 代码自动生成的数据可视化代码 选择Claude AI 而非 ChatGPT的理由是前者更懂中文!具体可以参见我前面的两篇文章对比两者的中英文翻译的表现及使用安装等难易程度…...
热门影片怎么买票比较便宜,低价买电影票的方法,纯攻略!
有时候真的有被自己蠢到!看电影看了这么多年,竟然不知道电影票价格才9.9元、19.9元就能买到。之前我看电影动不动就是几十上百块,感觉好亏啊。 其实,我也不敢相信的,通过这些平台,同时在节假日甚至春节档期…...
Python通过SWIG调用C++时出现的ImportError问题解析
摘要 win10系统,编译器为mingw,按照教程封装C的一个类并用python调用,一步步进行直到最后一步运行python代码时,在python代码中import example时报错ImportError: DLL load failed while importing _example: The specified modul…...
3ds Max云渲染有多快,3ds Max云渲染怎么用?
本地渲染效果图和动画3D项目是一个非常耗时的过程,当在场景中使用未优化的几何体或在最终渲染中使用大量多边形模型时,诸如此类的变量最终会增加渲染项目所需的时间和处理器能力。随着提供的渲染服务的云渲染平台出现,越来越多动画师、艺术家…...
Java之线程安全
目录 一.上节回顾 1.Thread类常见的属性 2.Thread类中的方法 二.多线程带来的风险 1.观察线程不安全的现象 三.造成线程不安全现象的原因 1.多个线程修改了同一个共享变量 2.线程是抢占式执行的 3.原子性 4.内存可见性 5.有序性 四.解决线程不安全问题 ---synchroni…...
我有一个方法判断你有没有编程天赋
我有一个方法判断你有没有编程天赋 一 前言 基于知识的诅咒的原理 做一个敲击者很难。问题在于敲击者已拥有的知识(歌曲题目)让 他们想象不到缺乏这种知识会是什么情形。当他们敲击的时候,他 们不能想象听众听到的是那些独立的敲击声而不是…...
python 生成chart 并以附件形式发送邮件
import requests import json import pandas as pd import numpy as np import matplotlib.pyplot as plt data np.random.randn(5, 3)#生成chart def generate_line_chart(data):df pd.DataFrame(np.abs(data),index[Mon, Tue, Wen, Thir, Fri],columns[A, B, C])df.plot()…...
leetcode-035-搜索插入位置
题目及测试 package pid035; /*35. 搜索插入位置 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为 O(log n) 的算法。示例 1:输入: nums …...
读书笔记--数据治理之法
继续延续上一篇文章,对数据治理之法进行学习。数据治理之法是战术层面的方法,是一套涵盖8项举措的数据治理实施方法论,包括梳理现状与确定目标、能力成熟度评估、治理路线图规划、保障体系建设、技术体系建设、治理策略执行与监控、绩效考核与…...
送了老弟一台 Linux 服务器,它又懵了!
大家好,我是鱼皮。 前两天我学编程的老弟小阿巴过生日,我问他想要什么礼物。 本来以为他会要什么游戏机、Q 币卡、鼠标键盘啥的,结果小阿巴说:我想要一台服务器。 鱼皮听了,不禁称赞道:真是个学编程的好苗…...
CentOS 7(2009) 升级 GCC 版本
1. 前言 CentOS 7 默认安装的 gcc 版本为 4.8,但是很多时候都会需要用到更高版本的 gcc 来编译源码,那么本文将会介绍如何在线升级 CentOS 的 gcc 版本。 2. 升级 GCC (1). 安装 centos-release-scl; [imaginemiraclecentos7 ~]$ sudo yum…...
java非静态代码块和静态代码块介绍
代码块 SE.10.0…02.28 非静态普通代码块:定义在方法内部的代码块,不用任何关键字修饰,又名构造代码块、实例代码块 静态代码块:用static修饰的代码块 非静态代码块 public class Test {public static void main(String[] args…...
Golang中接口类型详解与最佳实践(二)
之前的文章《Golang中的interface(接口)详解与最佳实践》详细介绍了接口类型的定义、使用方法和最佳实践。接口类型使得编写可扩展、可维护和可复用的高质量代码变得更加容易。 如何判断是否实现了某个接口? 还是使用之前文章的例子,例如声明了如下一个…...
ChatGPT 探讨内存屏障的意内存
一、与 ChatGPT 探讨内存屏障的意内存 轻松的氛围,跟 ChatGPT 从内存屏障问题一直扯到CAP原理 我: 2023/4/14 17:48:09 那我可以理解为{ shared_var 1; asm volatile ("sfence" ::: "memory"); asm volatile ("lfence" …...
P1039 [NOIP2003 提高组] 侦探推理
此题难度为:提高/省选- 作者为:CCF_NOI 题目描述 明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明…...
模拟电路学习笔记 - 概念与结论
真空二极管,电子管ENIAC发源地,基础方法二极管双极管三极管场向管学习特性,最终运放运方的目的是运用,射频,计算…放大电路大功率元器件和微元器件学习他们的特性分粒 集成设计的角度,不要仅仅分析设计的前…...
Linux驱动开发:I2C子系统
目录 1、I2C简介 1.1 两根线 1.2 信号 1.3 写时序 1.4 读时序 1.5 I2C速率 1.6 I2C驱动框架简介 2、I2C设备驱动 2.1 I2C相关API 2.1.1 i2c_driver 2.1.2 注册:i2c_add_driver 2.1.3 注销:i2c_del_driver 2.1.4 module_i2c_driverÿ…...
[C++] 动态内存与智能指针
众所周知,C五大内存区:全局数据区(静态区)、代码区、栈区、堆区、常量区。 全局数据区(静态区):存放全局变量,静态数据和常量; 代码区:存放所有类成员函数和非成员函数代码,函数体的二进制代码。…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
