c++继承和派生(1)

news2024/11/18 23:48:25

目录

1.含义:从不同层面看的,同一种意思

2. 继承的使用场景 

1.  共同之处 

2.  迭代更新 

3.  代码重构 

3. 继承的基本语法 

4. 继承了什么 

1. 查看占用内存大小

2.  使用vs自带的功能查看类的内存分布

布局: 

3. 结果 

5. protected  -- 子类的特权

1)  三个访问权限 

2)子类的特权

3)同等对待 --  私有属性

4)总结 

6. 有父才有子  --  构造子类时,先构造其父类 

1)根据代码看 

2)调用哪个构造函数 

3)自己指定调用哪个构造函数。 

4)为什么要调用父类的构造函数 

7. 父与子有不同  --  子类中定义自己的成员

1)名称覆盖:

2)子类重写函数和父类不是同一个函数 

指向成员函数的函数指针: 

8. 家有家规 --  继承的三种方式 

1)public继承 

2)protected继承 

3)private继承 

4)继承方式和访问权限的区别 


 

1.含义:从不同层面看的,同一种意思

继承:  子类继承于父类。 

派生:  父类派生出子类。

2. 继承的使用场景 

1.  共同之处 

我们平时创建的类,如果两个类之间存在某种关系,或者说几个类之间具有一些共同的函数或者变量。那么就可以考虑将共同部分写成父类,使用这些函数和变量的类直接从父类继承就可以,避免写重复的代码。 

比如:写一个男孩类和一个女孩类,对于男孩和女孩,他们都有吃喝玩乐的方法,姓名,年龄等成员。这时候,可以将这些公有的部分设置成一个人类,让男孩和女孩类直接继承。 

2.  迭代更新 

如果我们之前写的类,需要更新新的功能,我们不需要去修改源码,直接继承之前那个类然后在子类中实现新的功能就可以了 

3.  代码重构 

就是修改之前写的没用继承的代码, 使用继承,提高代码的质量。

3. 继承的基本语法 

Father类:

class Father {
public:
	Father();
	Father(const char* name, int age);
private:
	string name;
	int age;
};

Son类:

class Son :public Father {
public:
	Son();
};

Son类继承了Father类,class Son : public Father  ,  在子类的后面加:,然后继承的方式public,然后父类Father。

4. 继承了什么 

那么子类到底从父类中继承了什么呢? 

	Father f("父类", 20);

	Son s;   

	cout << sizeof(f) << endl;
	cout << sizeof(s) << endl;

1. 查看占用内存大小

使用上面的Father类和Son类创建对象,计算大小。  注意:子类中只有无参构造。 

我们定义父类和子类对象,打印出两个对象的大小。 --  发现两个类的内存大小都是一样的。

 

2.  使用vs自带的功能查看类的内存分布

上面可能还不太直观,我们可以直接查看类的分布 

步骤: 1. 在项目名右键,选择属性    2.   选择c/c++,选择命令行  3. 然后添加 

 /d1 reportSingleClassLayoutSon -- 表示打印单类的布局。 想要打印哪个类的布局就在后面写

哪个类的名字。4. 确定  5. 编译代码,在输出窗口就能看到相应类的代码了。 

布局: 

  

上面就是子类Son的布局,

第一行表示,基类(就是父类)为Father, 第二行是成员变name(string类型在64为os中占40个字节),第三行是一个age变量(int 类型占4个字节)。 第四行是内存对齐(4个字节)。  

3. 结果 

你会发现,name和age是Father类里面的属性。 

其实子类可以从父类中继承,除父类构造函数析构函数外的所有成员都会被子类继承。 

那上面为什么没有其它成员函数呢,因为,成员函数并不是和对象存储在一起的。 

为什么不继承构造函数和析构函数:因为构造函数和析构函数的名字是父类的,继承到子类也没用。 

5. protected  -- 子类的特权

1)  三个访问权限 

public:          公有权限,在类内,子类内和类外都可以直接访问类中定义的成员 

private:      私有权限,只能在类内直接访问,在类外和子类中都无法直接访问,只能使用提供                         的public接口简介访问 

protected: 保护权限,可以直接在类内和子类中访问,无法在类外直接访问。

2)子类的特权

如果有一些数据,希望子类可以直接访问,不希望类外直接访问,那么定义成private就行。

3)同等对待 --  私有属性

对于private的属性,子类和外界都是一样的,都无法访问。但是,私有属性子类也继承了(前面的例子中),但是,编译器规定,由于这些属性是继承于父类的私有属性,所以在子类的内部是无法直接访问的。(要想访问也得调用父类提供的公共接口) 

4)总结 

对于子类,父类中的private,和public属性都可以在子类中直接访问,但是私有属性不可以。 

6. 有父才有子  --  构造子类时,先构造其父类 

1)根据代码看 

先看一段代码:  我们分别在子类和父类的构造函数中输出__FUNTION__(自己的函数名字),然后在主函数中,创建子类,来看一下子类和父类的构造函数调用情况 

int main(void) {

	Son s;   

	system("pause");

	return 0;
}

 

会发现,创建子类对象时,会先调用其父类的构造函数。 

2)调用哪个构造函数 

上面说到,要想构造子类对象,就会先调用父类的构造函数,但是构造函数有默认的,有参数的,应该调用哪一个呢? 

如果我们没有指定,编译器默认会调用父类的默认构造函数。(你可以在父类中只写有参数的构造,然后在子类构造函数处,就会报错--父类没有默认构造函数)从这一点就可以看出,当调用子类构造函数的时候,并且在未指定的情况下,编译器会默认调用父类的默认构造函数。 

3)自己指定调用哪个构造函数。 

Son::Son(const char* name, int age):Father(name,age){

	std::cout << __FUNCTION__ << std::endl;

	this->name = name;
	this->age = age;
}

我们可以看到,在子类构造函数的右侧 : 父类名(相应构造函数的参数),这样就可以指定当我们调用子类有参构造函数创建子类对象时, 会调用父类的有参构造函数。

当然,我们此处是在有参数构造处指定的,对于其它的构造函数,还是会调用父类的默认构造函数。 

4)为什么要调用父类的构造函数 

1. 一种解释,这是c++的语法的规定,也符合正常的环境,先有父亲再有儿子。

2. 另一个解释,就是我们一般会将属性设置为私有的,这样,在子类中无法直接访问从父类继承的成员,这时候就无法对这些属性进行初始化或者赋值了,那怎么办?

我们可以调用父类的构造函数来初始化这些数据,因为私有的变量,是可以在本类的函数中访问的。 所以,我们在:后写的,是函数调用,调用父类构造函数。 

3. 所以c++会在调用子类的构造函数的时候调用父类的构造函数,如果不写默认会调用默认构造函数。(前提,这些构造函数必须存在,否则会出错) 

7. 父与子有不同  --  子类中定义自己的成员

 子类不仅可以继承父类的成员,当然也可以有自己的成员。

class Son :public Father {
public:
	Son();
	Son(const char* name, int age);
private:
	int play;
};

 子类Son中定义了自己的数据成员,int play,当然也可以定义自己的成员函数。

1)名称覆盖:

其实类我们可以看做一个作用域,子类作用域是嵌套在父类作用域中的。 

1. 当我们,使用子类访问成员函数或者成员变量的时候,会先从子类的作用域找,没有的话会从父类的作用域中去找。(逐渐往外) 

 2. 当我们在子类中定义和父类之外的同名的变量或者函数的时候,那么就会对外部定义的同名变量和函数进行覆盖,使用子类对象访问的时候,会访问自己的对象和函数。(同名时) 

2)子类重写函数和父类不是同一个函数 

往往子类有时会对父类的函数进行重写,虽然它们名字相同但是并不是同一片内存(其实编译之后就不同了)。 

我们可以通过查看父类和子类的同名函数的地址来查看是否是同一个函数

指向成员函数的函数指针: 

C语言中我们学习过指向函数的函数指针,这里同理,定义一个函数指针,指向成员函数,然后就可以查看成员函数的地址。 

语法: 函数返回值  (函数所在类名::*指针变量)   =   &函数所在类名::函数名 

class Father {
public:
	void address();
protected:
	int age;
};

class Son :public Father {
public:
	void address();

private:
	int link;

};

 
void Father::address() {

	void (Father::*p)() = &Father::address;

	printf("%p\n",p);
}

void Son::address() {
	void (Son:: * p)() = &Son::address;

	printf("%p\n", p);
}

int main(void) {
	Father f;
	Son s;

	f.address();

	s.address();

	system("pause");

	return 0;
}

8. 家有家规 --  继承的三种方式 

前面继承语法中有一个访问方式public,还有两种,private,protected,这看起来和访问权限很类似,实则是不一样的。 

1)public继承 

public继承方式,继承父类的成员时, 不会改变父类成员的访问权限。

private  ->  private     public -> public    protected -> protected 

2)protected继承 

protected继承方式,继承父类的成员时,会将public转换为protected,其它权限不变 

private ->  private       public -> protected    protected -> protected 

3)private继承 

provate继承方式,继承父类的成员时,会将所有访问权限都转换为private 

private -> private       public ->  private    protected -> private 

4)继承方式和访问权限的区别 

虽然继承方式和访问权限都是三个且都是public,private,protected。但是却不相同。 

继承方式可以说是限制外界的。 

对于子类,继承方式无论是什么,在类的内部都可以直接访问父类的public,protected的成员。 

那要那么多继承方式做什么?  --  是用来限制外界的。

我们在外界定义子类的对象,通过子类对象调用继承的成员,如果是public方式,那就可以调用对应父类的public成员,protected继承和private继承是不可以在类外进行访问的。  

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

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

相关文章

软件测试|使用Python提取出语句中的人名

简介 在自然语言处理&#xff08;NLP&#xff09;中&#xff0c;提取文本中的人名是一项常见的任务。Python作为一种流行的编程语言&#xff0c;拥有强大的NLP库和工具&#xff0c;使我们能够轻松地进行这项任务。在本文中&#xff0c;我们将使用Python示例来演示如何提取文本…

Linux第23步_安装windows下的STM32CubeProgrammer软件和安装 DFU驱动程序

STM32CubeProgrammer软件是通过USB3.0接口烧写系统软件。 STM32CubeProgrammer需要java运行环境&#xff0c;因此需要安装JAVA软件。 Java 运行环境版本必须是 V1.7 及以上&#xff0c;一定要用 64位的&#xff0c;和win系统一致&#xff0c;否则使用 STM32CubeProgrammer烧…

深入解析JavaScript中的函数绑定和命名函数表达式

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 函数是JavaScript中最重要的组成部分之一。但是函数的this绑定和作用…

Power Query 中常用的数据清洗、转换操作

&#xff08;一&#xff09;数据筛选、保留、删除、去重 1、数据筛选 操作步骤 选中列——点击列名右侧箭头——进行筛选 可选操作 勾选文本筛选器&#xff1a;等于/不等于、开头是/开头不是、结尾是/结尾不是、包含/不包含数字筛选器&#xff1a;等于/不等于、大于/大于等于…

harbor https

harbor https部署 准备docker-compose安装https 证书harbor安装访问harbor推镜像到harbor 准备 192.168.112.99&#xff0c;harbor&#xff0c;centos7 192.168.112.3&#xff0c;测试机&#xff0c;centos7 docker版本&#xff1a;docker-ce 20.10.16&#xff08;部署参考&a…

主流浏览器设置代理IP之搜狗浏览器

给浏览器设置代理IP是目前代理IP的主流使用场景之一&#xff0c;接下来小编就手把手教你如何对搜狗浏览器进行代理IP设置 注&#xff1a;本次使用IP来源于携趣代理平台 搜狗浏览器内设置IP代理 1、首先需要进入浏览器【设置】 2.点击【代理设置】选择【代理服务器设置】然后进…

ITE IT6801FNBX HDMI接收器 芯片

一、物料概述 IT6801FN是一款单端口HDMI接收器&#xff0c;可在HDMI1.4和MHL2.1双模式下工作&#xff0c;完全兼容MHL2.1、HDMI 1.4a、HDMI 1.4a3D和HDCP1.4&#xff0c;还可向后兼容DVI 1.0规格。IT6801FN具有深彩色功能&#xff08;高达36位&#xff09;&#xff0c;可确保接…

腾讯开源AI工具PhotoMaker,无需训练模型就能保持脸部一致随意换装。

腾讯开源AI工具PhotoMaker&#xff0c;无需训练模型就能保持脸部一致随意换装。 最近&#xff0c;AI文本到图像生成领域取得了显著进展&#xff0c;然而&#xff0c;现有的个性化生成方法已经无法同时满足用户的需求&#xff0c;这次腾讯发布了PhotoMaker框架&#xff0c;可以在…

IaC基础设施即代码:Terraform 通过后端使用 alicloud的OSS 实现资源管理

目录 一、实验 1.环境 2.Windows创建Terraform后端项目 3.Windows实例化Terraform后端项目 3.Windows给Terraform项目添加alicloud阿里云OSS &#xff08;实现代码与资源分离&#xff09; 4.Windows给Terraform项目添加封装的模块 5.Terraform通过后端使用 alicloud阿里…

价值7500的在线授权网站源码支持IP+域名+双向授权全开源

PHP授权验证更新系统完整版&#xff0c;一键更新系统&#xff0c;一键卡密生成自助授权功能&#xff0c;域名ip双重验证功能等等 修复盗版检测&#xff0c;确保实时查看盗版 修复在线加密系统&#xff0c;一键加密 授权系统几乎所有的程序都能整合使用,包括您的app和计算机程序…

el-table右固定最后一列显示不全或者是倒数第二列无边框线

问题图片&#xff1a; 解决方式1&#xff1a; >>>.el-table__row td:not(.is-hidden):last-child { border-left:1px solid #EBEEF5; } >>>.el-table__header th:not(.is-hidden):last-child{ border-left:1px solid #EBEEF5; } >>>.el-table__head…

文件压缩完还是过大怎么办?这些参数你设置了吗?

不同的压缩算法对不同类型的文件可能有不同的效果。尝试使用不同的压缩算法、压缩模式、调整压缩工具的参数或者设置输出的文件格式等方法解决问题。下面以嗨格式压缩大师作为操作示范。 方法一&#xff1a;对文件进行分类压缩 将文件按照视频、图片、pdf、word、PPT分类压缩…

uni-app的项目创建和环境搭建

uni-app 是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;开发者编写一套代码&#xff0c;可发布到iOS、Android、Web&#xff08;响应式&#xff09;、以及各种小程序&#xff08;微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝&#xff09;、快应用等多个平台。 第一步…

Linux内核架构和工作原理详解(二)

Linux内核体系结构简析简析 图1 Linux系统层次结构 最上面是用户&#xff08;或应用程序&#xff09;空间。这是用户应用程序执行的地方。用户空间之下是内核空间&#xff0c;Linux 内核正是位于这里。GNU C Library &#xff08;glibc&#xff09;也在这里。它提供了连接内核…

游戏素材永不缺,免费在线AI工具Scenario功能齐全,简单易用

Scenario是一个在线的AI驱动的工具&#xff0c;主要用于游戏艺术创作。它提供了一套全面的功能&#xff0c;旨在帮助游戏开发者创建与其独特风格和艺术方向相符的独特、高质量的游戏艺术。Scenario的突出特点之一是它的微调能力&#xff0c;允许用户根据独特的风格和艺术方向训…

Linux 内核被冬季风暴 “封印“

Linus Torvalds在内核邮件列表上宣布&#xff0c;由于他所在的美国俄勒冈州波特兰地区受到严重冬季风暴的影响&#xff0c;导致网络和电力中断。波特兰及其周边地区气温急降至零下 -10C&#xff0c;因此他不得不临时中断对Linux 6.8内核的合并窗口操作。 Linus于1月7日发布了Li…

最优订单执行算法相关论文介绍

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

Resemble Enhance音频失真损坏修复AI工具:一个开源语音超分辨率AI模型

Resemble Enhance是一款强大的音频处理工具&#xff0c;可以将嘈杂的录音转化为清晰而有力的声音&#xff0c;为用户提供更优质的听觉体验。这个工具不仅可以有效去除录音中的各种噪声和杂音&#xff0c;还能够恢复音频失真并扩展音频带宽&#xff0c;使原本的声音听起来更加清…

迈向未来的求职征程:广州大学全职特聘讲师入职经历

迈向未来的求职征程&#xff1a;我的广州大学全职特聘讲师入职经历 2023博士毕业求职经验贴 在人生的职业旅程中&#xff0c;每一次求职都是一个新的冒险&#xff0c;而我最近的一次求职经历&#xff0c;是迈向教育领域的激动人心的一步。成为广州大学全职特聘讲师的入职之路…

QT 绘图与重绘事件

代码实现仪表盘 .cpp #include "widget.h" #include "ui_widget.h"#include <QPainter> #include <QPen> #include <QBrush>#include <QDebug> Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->…