【C++】类和对象-继承

news2024/10/5 19:20:01

0.前言

在这里插入图片描述

1.基本语法

在这里插入图片描述
在这里插入图片描述

继承的用处就是极大的减少代码的重复性,如果没有用继承,看看以下代码,你知道了。。。。

基本实现代码:

#include <iostream>
using namespace std;
/******************************************/

void test01();

/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

//Java页面
class Java {
public:
	void header() {
		cout << "首页、公开课、登录、注册...(公共头部)" << endl;
	}
	void footer() {
		cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
	}
	void left() {
		cout << "Java,Python,C++...(公共分类列表)" << endl;
	}
	void content() {
		cout << "Java学科视频" << endl;
	}
};
//Python页面
class Python {
public:
	void header() {
		cout << "首页、公开课、登录、注册...(公共头部)" << endl;
	}
	void footer() {
		cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
	}
	void left() {
		cout << "Java,Python,C++...(公共分类列表)" << endl;
	}
	void content() {
		cout << "Python学科视频" << endl;
	}
};
//Cpp页面
class Cpp {
public:
	void header() {
		cout << "首页、公开课、登录、注册...(公共头部)" << endl;
	}
	void footer() {
		cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
	}
	void left() {
		cout << "Java,Python,C++...(公共分类列表)" << endl;
	}
	void content() {
		cout << "Cpp学科视频" << endl;
	}
};

void test01() {
	//Java页面
	cout << "Java下载视频页面如下:" << endl;
	Java ja;
	ja.header();
	ja.footer();
	ja.left();
	ja.content();
	cout << "——————————————————————————" << endl;

	//Python页面
	cout << "Python下载视频页面如下:" << endl;
	Python py;
	py.header();
	py.footer();
	py.left();
	py.content();
	cout << "——————————————————————————" << endl;

	//Cpp页面
	cout << "Cpp下载视频页面如下:" << endl;
	Cpp cpp;
	cpp.header();
	cpp.footer();
	cpp.left();
	cpp.content();
	cout << "——————————————————————————" << endl;
}

继承实现代码

#include <iostream>
using namespace std;
/******************************************/

void test01();

/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

//公共页面
class BasePage {
public:
	void header() {
		cout << "首页、公开课、登录、注册...(公共头部)" << endl;
	}
	void footer() {
		cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
	}
	void left() {
		cout << "Java,Python,C++...(公共分类列表)" << endl;
	}
};

//Java页面
class Java : public BasePage {
public:
	void content() {
		cout << "Java学科视频" << endl;
	}
};
//Python页面
class Python : public BasePage {
public:
	void content() {
		cout << "Python学科视频" << endl;
	}
};
//Cpp页面
class Cpp :public BasePage {
public:
	void content() {
		cout << "Cpp学科视频" << endl;
	}
};

void test01() {
	//Java页面
	cout << "Java下载视频页面如下:" << endl;
	Java ja;
	ja.header();
	ja.footer();
	ja.left();
	ja.content();
	cout << "——————————————————————————" << endl;

	//Python页面
	cout << "Python下载视频页面如下:" << endl;
	Python py;
	py.header();
	py.footer();
	py.left();
	py.content();
	cout << "——————————————————————————" << endl;

	//Cpp页面
	cout << "Cpp下载视频页面如下:" << endl;
	Cpp cpp;
	cpp.header();
	cpp.footer();
	cpp.left();
	cpp.content();
	cout << "——————————————————————————" << endl;
}

2.继承方式

在这里插入图片描述
在这里插入图片描述

#include <iostream>
using namespace std;
/******************************************/

//公共继承
class Base1 {
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};
class Son1 :public Base1 {
public:
	void func() {
		m_A = 100;//父类中的公共权限成员 到子类中依然是公共权限
		m_B = 100;//父类中的保护权限成员 到子类中依然是保护权限
		//m_C = 100;//父类中的私有权限成员 子类访问不到
	}
};
void test01() {
	Son1 s1;
	s1.m_A = 100;  //到Son1中 m_B是公共权限 类外可以访问
	//s1.m_B = 100;//到Son1中 m_B是保护权限 类外访问不到
	//s1.m_C = 100;//到Son1中 m_B是私有权限 类外访问不到
}

//保护继承
class Base2 {
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};
class Son2 :protected Base2 {
public:
	void func() {
		m_A = 100;//父类中公共成员,到子类中变为了保护权限
		m_B = 100;//父类中保护成员,到子类中变为了保护权限
		//m_C = 100;//父类中私有成员 子类访问不到
	}
};
void test02() {
	Son2 s2;
	//s2.m_A = 100;//在Son2中 m_A变为保护权限 ,因此类外访问不到
	//s2.m_B = 100;//在Son2中 m_B保护权限 不可以访问
	//s2.m_C = 100;//在Son2中 m_B私有权限 不可以访问
}

//私有继承
class Base3 {
public:
	int m_A = 100;
protected:
	int m_B = 100;
private:
	int m_C = 100;
};
class Son3 :private Base3 {
public:
	void func() {
		m_A = 100;//父类中公共成员,到子类中变为了私有权限
		m_B = 100;//父类中保护成员,到子类中变为了私有权限
		//m_C = 100;//父类中私有成员 子类访问不到
	}
};
void test03() {
	Son3 s3;
	//s3.m_A = 100;//在Son3中 m_A变为私有权限 ,因此类外访问不到
	//s3.m_B = 100;//在Son3中 m_A变为私有权限 ,因此类外访问不到
	//s3.m_C = 100;//在Son3中 m_B私有权限 不可以访问
}

//孙类访问父类
class GrandSon2 :public Son2 {
public:
	void func() {
		m_A = 100;//在Son2中 m_A变成了保护权限 孙类可以类内访问
		m_B = 100;//在Son2中 m_B仍然为保护权限 孙类可以类内访问
		//m_C = 100;//父类中私有成员 子类访问不到 孙类也访问不到
	}
};

class GrandSon3 :public Son3 {
public:
	void func() {
		//m_A = 100;//在Son3中 m_A变成了私有权限 孙类访问不到
		//m_B = 100;//在Son3中 m_B变成了私有权限 孙类访问不到
		//m_C = 100;//父类中私有成员 子类访问不到 孙类也访问不到
	}
};

/******************************************/
int main()
{
	/******************************************/
	test01();
	test03();
	test02();

	/******************************************/
	system("pause");

	return 0;
}

3.继承中的对象模型

在这里插入图片描述
在这里插入图片描述

代码

#include <iostream>
using namespace std;
/******************************************/
//继承中的对象模型
class Base {
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};
class Son :public Base {
public:
	int m_D;
};

//利用开发人员命令提示工具查看对象模型
//跳转盘符 E:
//跳转文件路径 cd 具体路径下
//查看命名
//cl /d1 reportSingleClassLayout类名 文件名
//然后按tab健

void test01() {
	//输出为:16
	//父类中所有非静态成员属性都会被子类继承下去
	//父类中私有成员属性 是被编译器给隐藏了,因此是访问不到,但是确实是被继承下去了
	cout << "size of Son = " << sizeof(Son) << endl;
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

利用开发人员命令提示工具查看对象模型:
在这里插入图片描述
其具体步骤如下:
在这里插入图片描述
在这里插入图片描述
如果不清楚,去跳转网址:

https://www.bilibili.com/video/BV1et411b73Z?p=129&spm_id_from=pageDriver&vd_source=fb8dcae0aee3f1aab700c21099045395

从05:55开始观看

4.继承中构造和析构顺序

在这里插入图片描述
**总结:**继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反

#include <iostream>
using namespace std;
/******************************************/
//继承中的构造和析构函数
class Base {
public:
	Base() {
		cout << "Base的构造函数!" << endl;
	}
	~Base() {
		cout << "Base的析构函数!" << endl;
	}
};

class Son:public Base {
public:
	Son() {
		cout << "Son的构造函数!" << endl;
	}
	~Son() {
		cout << "Son的析构函数!" << endl;
	}
};

void test01() {
	//继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反
	Son s;
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

5.继承同名成员处理方式

在这里插入图片描述
在这里插入图片描述
代码

#include <iostream>
using namespace std;
/******************************************/
class Base {
public:
	Base() {
		m_A = 100;
	}
	void func() {
		cout << "Son-func()调用" << endl;
	}
	void func(int a) {
		cout << "Base-func(int a)调用" << endl;
	}
public:
	int m_A;
};

class Son :public Base {
public:
	Son() {
		m_A = 200;
	}

	//当子类与父类拥有同名的成员函数,子类会隐藏父类中所有版本的同名成员函数
	//如果想访问父类中被隐藏的同名成员函数,需要加父类的作用域
	void func() {
		cout << "Son-func()调用" << endl;
	}

public:
	int m_A;
};

void test01() {
	Son s;
	//子类对象加作用域才可以访问到父类同名成员
	cout << s.m_A << endl << s.Base::m_A << endl;
	s.func();
	s.Base::func();
	s.Base::func(12);
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

结果
在这里插入图片描述

6.继承同名静态成员处理方式

在这里插入图片描述
在这里插入图片描述
代码

#include <iostream>
using namespace std;
/******************************************/
class Base {
public:
	static int m_A;

	static void func() {
		cout << "Base-func()调用" << endl;
	}

	static void func(int a) {
		cout << "Base-func(int a)调用" << endl;
	}
};
int Base::m_A = 100;
class Son :public Base {
public:
	static int m_A;

	static void func() {
		cout << "Son-func()调用" << endl;
	}
};
int Son::m_A = 200;

void test01() {
	cout << "同名成员属性:" << endl;
	//1、通过对象访问
	cout << "通过对象访问:" << endl;
	Son s;
	cout << "Son m_A = " << s.m_A << endl;
	cout << "Base m_A = " << s.Base::m_A << endl;

	//2、通过类名访问
	cout << "通过类名访问:" << endl;
	cout << "Son m_A = " << Son::m_A << endl;
	//第一个::代表通过类名方式访问  第二个::代表访问父类作用域下的m_A
	cout << "Base m_A = " << Son::Base::m_A << endl << endl << endl;;

	cout << "同名函数属性:" << endl;
	//1、通过对象访问
	cout << "通过对象访问:" << endl;
	Son s2;
	s2.func();
	s2.Base::func();
	//2、通过类名访问
	cout << "通过类名访问:" << endl;
	Son::func();
	Son::Base::func();
	//出现同名,子类会隐藏掉父类中所有同名成员函数,需要加作用域访问
	Son::Base::func(100);
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

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

7.多继承语法

在这里插入图片描述
在这里插入图片描述
代码:

#include <iostream>
using namespace std;
/******************************************/
class Base1 {
public:
	Base1() {
		m_A = 100;
	}
public:
	int m_A;
};
class Base2 {
public:
	Base2() {
		m_A = 200;//开始是m_B 不会出问题 ,但是改为m_A就出现不明确
	}
public:
	int m_A;
};

//语法: class 子类:继承方式 父类1,继承方式 父类2,.....
class Son :public Base1, public Base2 {
public:
	Son() {
		m_A = 300;
		m_D = 400;
	}
public:
	int m_A;
	int m_D;
};

//多继承容易产生成员同名的情况
//通过使用类名作用域可以区分调用哪个基类的成员
void test01() {
	Son s;
	cout << "size of Son = " << sizeof(s) << endl;
	cout << "Base1:m_A = " << s.Base1::m_A << endl;
	cout << "Base2:m_A = " << s.Base1::m_A << endl;
	cout << "Son:m_A = " << s.m_A << endl;
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

结果:
结果
利用开发人员命令提示工具查看对象模型:
在这里插入图片描述

8.菱形继承

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果没有用虚继承,会导致有歧义,相当于两个父类、多继承的不明确问题
在这里插入图片描述
代码

#include <iostream>
using namespace std;
/******************************************/
class Animal {
public:
	int m_Age;
};
//继承前面加virtual关键字后,变为虚继承
//此时公开的父类Animal称为虚基类
class Sheep :virtual public Animal {};
class Tuo :virtual public Animal {};
class SheepTuo :public Sheep, public Tuo {};

void test01() {
	SheepTuo st;
	st.Sheep::m_Age = 19;
	st.Tuo::m_Age = 29;
	
	cout << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
	cout << "st.Tuo::m_Age = " << st.Tuo::m_Age << endl;
	cout << "st.m_Age = " << st.m_Age << endl;
}
/******************************************/
int main()
{
	/******************************************/
	test01();

	/******************************************/
	system("pause");

	return 0;
}

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

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

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

相关文章

8.5周六|Move Dev Meetup厦门站不见不散

Move Dev Meetup是由MoveFuns DAO发起的线下研讨会&#xff0c;旨在为参与的开发者提供深入了解Move语言机会。截至目前为止&#xff0c;Meetup已在成都、深圳、杭州等多个城市举办。Move Dev Meetup厦门站将在8月5日&#xff08;本周六&#xff09;举办&#xff0c;Sui将作为支…

观察级水下机器人使用系列之五三维激光扫描仪

本文主要讲观察级水下机器人Valor配套的三维激光扫描仪&#xff0c;它是近年来ROV的主力光学设备。三维激光扫描仪是Voyis&#xff08;原公司为2G Robotics&#xff09;公司生产的&#xff0c;型号为ULS-500 Micro。 ​编辑​ ULS-500 Micro的技术参数如下图。ULS-500 Pro扫描…

关于docker的一些深入了解

本文将深入介绍一下docker方面的知识&#xff0c;不尽完全&#xff0c;慢慢完善。 进程 进程的概念 在介绍docker的相关知识前&#xff0c;先了解一下相关概念。进程就是系统中正在运行的程序&#xff0c;进程是操作系统的概念&#xff0c;每当我们执行一个程序时&#xff0…

关于 Ubuntu 长按 shift 无效, 按 Esc 直接进入 grub 改密码的解决方法

本次长按shift没有反应&#xff0c;直接进入了系统界面&#xff0c;所以改用长按Esc键&#xff0c;步骤如下&#xff1a; 1. 长按esc&#xff0c;进入grub>提示 2.输入grub>normal &#xff0c;回车 3.上一步回车后&#xff0c;继续敲击Esc &#xff0c;出现grub界面 …

rdp、ftp协议的密码爆破

远程桌面 rdp协议 3389 文件传输 FTP协议 20 21 攻击方&#xff1a;Kali 测试方&#xff1a;Win7 两台都要在同一网段 密码爆破工具 hydra九头蛇 hydra&#xff08;九头蛇&#xff09;是著名黑客组织thc的一款开源的暴力破解密码工具&#xff0c;功能非常强大&#xff0c;ka…

Emacs之远程开发C++配置: emacs + tramp + clangd(一百二十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

大数据学习教程:Linux高级教程(下)

四、大数据集群服务器搭建 1. 新增Linux服务器 1.1、克隆虚拟机 学习环境中&#xff0c;一般使用VMware虚拟机克隆Linux系统&#xff0c;用来进行集群服务器的搭建。 VMware支持两种类型的克隆&#xff1a;完整克隆、链接克隆 完整克隆是和原始虚拟机完全独立的一个复制&…

系统架构设计师_备考第2天(计算机组成与体系结构)

文章目录 考频&#xff08;3分左右&#xff09;一、计算机结构二、CPU组成三、冯诺依曼结构和哈弗结构四、层次化存储结构五、Cache 考频&#xff08;3分左右&#xff09; 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 计算机结构&#xff08;★&#xff0…

魔法上网端口号被占用通过端口号找到进程并且杀掉进程随笔

Windows11系统由于魔法上网被异常关闭导致再次启动的时候报出端口号被占用问题记录以前忘记的通过端口杀掉进程相关操作。 在命令行&#xff08;winr,输入cmd&#xff09;中输入: netstat -ano 可以看到本机正在使用的ip地址和端口号如图&#xff1a; 在命令行&#xff08;wi…

Array.prototype.slice.call()方法详解

slice:用来截取截取字符串方法Array: javascript的一个引用类型&#xff0c;其原型prototype上有一个方法叫slicecall和apply &#xff1a; 用来改变对象中函数内部的this引用&#xff0c;使得函数可以随便换‘妈妈’ 为什么不直接用 arguments.slice(1)呢 不是一样的么? 答案…

springboot第33集:nacos图

./startup.sh -m standalone Nacos是一个内部微服务组件&#xff0c;需要在可信的内部网络中运行&#xff0c;不可暴露在公网环境&#xff0c;防止带来安全风险。Nacos提供简单的鉴权实现&#xff0c;为防止业务错用的弱鉴权体系&#xff0c;不是防止恶意攻击的强鉴权体系。 鉴…

门面模式:简化复杂系统的接口调用

门面模式&#xff1a;简化复杂系统的接口调用 什么是门面模式&#xff1f; 门面模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式&#xff0c;它提供了一个简单的接口&#xff0c;用于访问复杂子系统中的一组接口。门面模式通过封装子系统的复杂性&#xff0…

如何免费制作中小学分班查询系统?

暑假即将结束&#xff0c;新学年即将开始&#xff0c;学校面临着一个重要任务&#xff1a;学生分班。不论是新生入学还是低年级升入高年级&#xff0c;都需要进行分班工作。这对负责分班的老师们来说&#xff0c;增加了相当大的工作量和挑战。 在开学前&#xff0c;如何快速解…

排序八卦炉之插入和希尔

文章目录 1.插入排序1.1代码1.2复杂度 2.希尔排序2.1代码2.2复杂度2.3算法解析 1.插入排序 1.1代码 //插入排序1.0 /* void InsertSort(int* a, int n) {//i&#xff1a; 0 -- 倒数第2个元素for (int i 0; i < n - 1; i){//end记录iint end i;//tmp记录end后一个值int tm…

ios_base::out和ios::out、ios_base::in和ios::in、ios_base::app和ios::app等之间有什么区别吗?

2023年8月2日&#xff0c;周三晚上 今天我看到了这样的两行代码&#xff1a; std::ofstream file("example.txt", std::ios_base::out);std::ofstream file("example.txt", std::ios::out);这让我产生了几个疑问&#xff1a; 为什么有时候用ios_base::o…

物联网潜在的巨大价值在于大数据分析

物联网潜在的巨大价值在于大数据分析 从数据里去挖掘市场或者用户的精准需求。 往小的说&#xff0c;后台可以统计用户家里各各插座一年甚至更久的用电情况&#xff0c;这些数据也可以通过app或者小程序展现给用户。 用户可以很直观看到自己一年的用电情况&#xff0c;哪个家…

2.6 伽马校正 一、Gamma校正

一、Gamma校正 颜色空间 通用&#xff1a;sRGB 电影&#xff1a;DCI-P3 电视&#xff1a;Rec-709、PAL等 印刷&#xff1a;CMYK、Adobe RGB 传递函数 我们知道了颜色的颜色值&#xff0c;要在电子设备上显示&#xff0c;就要把它转换为视频信号&#xff0c;传递函数就是用…

Linux上安装Keepalived,多台Nginx配置Keepalived(保姆级教程)

目录 一、yum安装 第一步&#xff1a;下载 第二步&#xff1a;编辑Keepalived配置文件&#xff08;第一台&#xff09; 第三步&#xff1a;编辑Keepalived配置文件&#xff08;第二台&#xff09; 第四步&#xff1a;我们在本机利用cmd ping一下 一、yum安装 第一步&…

[国产MCU]-BL602开发实例-开发环境搭建

开发环境搭建 文章目录 开发环境搭建1、BL602介绍2、软件准备3、源码编译3.1 编译内置工程3.2 自定义工程、自定义组件添加与编译4、固件下载BL602 是一款Wi-Fi + BLE组合的芯片组,用于低功耗和高性能应用开发。无线子系统包含2.4G无线电,Wi-Fi 802.11b/g/n和BLE 5.0 基带/MA…

【编程范式】聊聊编程的本质

任何算法都会有两个部分&#xff0c; 一个是 Logic 部分&#xff0c;这是用来解决实际问题的。另一个是 Control 部分&#xff0c;这是用来决定用什么策略来解决问题。Logic 部分是真正意义上的解决问题的算法&#xff0c;而 Control 部分只是影响解决这个问题的效率。程序运行…