C++继承,语法+案例,超详细!!

2023-11-08

类的继承

继承是代码重用的一种方法。

通过继承创建的新类称为“派生类”或“子类”,被继承的类称为“基类”或“父类”。

继承即子类无需重新编写父类成员代码的情况下继承父类所有的成员,子类只需书写新增成员的代码

语法:

class 子类名 : 继承方式 父类名1 , 继承方式 父类名2 , ..... , 继承方式 父类名n 
{
	派生类的成员
};

2

private:1.该类中的函数、2.友元函数访问。不能被任何其他访问,该类的对象也不能访问。
protected:1.该类中的函数、2.子类的函数、3.友元函数访问。但该类的对象不能访问。
public:1.该类中的函数、2.子类的函数、3.其友元函数,4.该类的对象访问

类的继承 举例

举例:

#include<iostream>
using namespace std;
class Student
{
	int id;
	string name;
	int age;
	public:
		void SetIn(int _id,string _name,int _age)
		{
			id = _id;
			name = _name;
			age = _age;	
		}	
		void Print()
		{
			cout<<"id:"<<id<<endl<<"name:"<<name<<endl<<"age:"<<age<<endl;
		}
};
class Graduate:public Student		//继承
{
	string degree;		//新增数据成员
	public:
		void SetIn_G(int _id,string _name,int _age,string _degree)
		{
			SetIn(_id,_name,_age);			//调用父类成员函数
			
			degree = _degree;		
		}
		void Print()					//与父类成员函数同名 
		{
			Student::Print();	//调用父类成员函数(因为同名,所以需要加作用域)
			cout<<"degree:"<<degree<<endl;
		}
		void Print_G()			 
		{
			Student::Print();//Print();	调用父类成员函数(不同名,所以直接调用)
			//但是跟上面  void Print() 撞名了,所以必须要加作用域,实际上可以用注释			的 Print()
			cout<<"degree:"<<degree<<endl;
		}
};
int main()
{
	Graduate G1;
	G1.SetIn_G(1,"张三",20,"计算机");	//调用子类的成员函数
	G1.Print();					//调用子类的打印成员函数(默认父类打印函数被隐藏)
	cout<<endl;
	G1.Student::Print();		//调用父类的打印函数
	cout<<endl;
	G1.Print_G();				//调用不同名的子类打印函数(直接调用)
	return 0;
} 

37

总结:

1、继承中,先调用父类构造函数,再调用子类构造函数,析构函数顺序与构造函数相反

2、若父类与子类成员函数同名,子类直接调用则是子类中的同名函数,子类加作用域才能访问父类同名函数,格式:子类名.父类名::同名函数;

菱形继承

菱形继承概念:

​ 两个子类继承同一个父类

​ 又有某个类同时继承着两个派生类

​ 这称为菱形继承或钻石继承

4

菱形继承的问题

1、狮子继承了动物的数据,老虎继承了动物的数据,当狮虎兽使用数据时,就会产生二义性

二义性:指无法直接通过变量名进行读取,需要通过域(::)成员运算符进行区分

2、狮虎兽继承了来自动物的数据且继承了两份,其实只需要一份

举例:

#include<iostream>
using namespace std;
class Animal
{
	public:
		int age;
};
class Sheep : public Animal
{

};
class Camel : public Animal
{

}; 
class Alpace : public Sheep , public Camel
{
		d
};
void test()
{
	Alpace a;
			//当菱形继承,两个父类拥有相同数据,需要用作用域区分
	a.Sheep::age = 20;		
	a.Camel::age = 1;
	cout<<"a.Sheep:"<<a.Sheep::age<<endl;
	cout<<"a.Camel:"<<a.Camel::age<<endl;
}
int main()
{
	test();
	return 0;
}

1

明明只需要一个age成员函数,但是却出现两个,造成浪费

解决菱形继承问题的办法是 虚继承

虚继承

虚继承是指在定义派生类时,通过关键字virtual来强制指定所继承的基类为虚基类

语法:

	class  子类 : virtual 继承方式 父类
	{
		子类新增的数据成员和成员函数
	}

5

举例

#include<iostream>
using namespace std;
class Animal
{
	public:
		int age;
};
class Sheep :virtual public Animal
{

};
class Camel :virtual public Animal
{

}; 
class Alpace : public Sheep , public Camel
{
		
};
void test()
{
	Alpace a;
	a.Sheep::age = 20;
	cout<<"a.Sheep:"<<a.Sheep::age<<endl;
	cout<<"a.Camel:"<<a.Camel::age<<endl;
	
	a.Camel::age = 1;
	cout<<"a.Sheep:"<<a.Sheep::age<<endl;
	cout<<"a.Camel:"<<a.Camel::age<<endl;
	
	a.Camel::age ++; 	
	cout<<"a.Sheep:"<<a.Sheep::age<<endl;
	cout<<"a.Camel:"<<a.Camel::age<<endl;
}
int main()
{
	test();
	return 0;
}

3

虽然继承了两个相同的数据,但是这两个相同的数据的地址是相同的

#include<iostream>
using namespace std;
class Person
{
	int no;
	string name;
	
	public:
		void Set_P(int _no,string _name)		//构造函数不能是虚函数
		{
			no = _no;
			name = _name;
		}
		void Print()
		{
			cout<<"编号:"<<no<<endl;
			cout<<"姓名:"<<name<<endl;
		}
};
class Student:virtual public Person
{
	protected:
		int grade;
		int score;
	
	public:
		void Set_S(int _grade,int _score,int _no,string _name)
		{
			Set_P(_no,_name);
			grade = _grade;
			score = _score;
		}
		void Print()
		{
			Person::Print();
			cout<<"年级:"<<grade<<endl;
			cout<<"成绩:"<<score<<endl;
		}
};
class Workers:virtual public Person
{
	protected:
		string title;
		string department;
	
	public:
		void Set_W(int _no,string _name,string _title,string _department)
		{
			Set_P(_no,_name);
			title = _title;
			department = _department;
		}	
		void Print()
		{
			Person::Print();
			cout<<"职称:"<<title<<endl;
			cout<<"部门:"<<department<<endl;
		}
};
class Opstudent:public Student,public Workers
{
	public:
		void Set_O(int _grade,int _score,int _no,string _name,string _title,string _department)
		{
			Set_W(_no,_name,_title,_department);
			Set_S(_grade,_score,_no,_name);
		}
		void Print()
		{
			Person::Print();
			cout<<"年级:"<<grade<<endl;
			cout<<"成绩:"<<score<<endl;
			cout<<"职称:"<<title<<endl;
			cout<<"部门:"<<department<<endl;
		}
};
int main()
{
	Student s1;
	s1.Set_S(1,100,1,"张三");
	s1.Print();
	cout<<endl;
	
	Workers w1;
	w1.Set_W(1,"张三","组长","营销");
	w1.Print(); 
	cout<<endl;
	
	Opstudent o1;
	o1.Set_O(1,100,1,"张三","组长","营销");
	o1.Print();
	
	return 0;
}

详细规则请看 虚函数与纯虚函数

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++继承,语法+案例,超详细!! 的相关文章

  • 如何获取正在访问 ASP.NET 应用程序的当前用户?

    为了获取系统中当前登录的用户 我使用以下代码 string opl System Security Principal WindowsIdentity GetCurrent Name ToString 我正在开发一个 ASP NET 应用程
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 按成员序列化

    我已经实现了template
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • 重载<<的返回值

    include
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • 从数据库中读取时间相差八个小时及格式不正确问题

    前端从数据库中读取时间数据的时候 需要关心的有格式问题和时间不一致问题 1 格式问题 有时读取时间数据是一长串的long类型数字 此数字表示的是自从公元年开始到现在所过的时间长度 此时在domain中 需要观察自己书写的时间对应类型是否写成
  • intel性能测试工具VTune的功能和用法介绍

    转自 https blog csdn net WY stutdy article details 79106501 https software intel com en us node 256997 1 VTune介绍 VTune可视化性
  • springboot将http改造成https

    springboot的项目天然的就是http的 但是有时候客户觉得http不安全 想要使用https的请求访问怎么处理 话不多少 上重点 https是对http进行ssl加密的一种协议 简单来说就是更安全 那么要怎么做呢 首先要生成证书 这
  • 看板的六大实践学习总结

    这次活动主要是学习看板的实践 看板的六大实践介绍如下 可视化 可视化价值项和价值流 story和它的流动 将问题和 瓶颈也在看板上可视化 可激发团队协作 限制在制品 通过限制各阶段的在实现的story 来加速流动 避免造成 交通 阻塞 考虑
  • 【C++】基础知识点回顾 中:函数重载、引用和内联函数

    前言 上篇文章我们介绍了C 基础知识中的命名空间 输入输出语句和缺省参数 上篇文章点击这里 今天 我们就来学习函数重载与引用 函数重载 定义 在编写代码时 当出现多个函数名相同的函数时 C 提供了一种方式 函数重载 使得当人们想使用哪个函数
  • CentOS7.x离线安装node及cnpm

    一 安装node 1 获取安装包放在 usr local 下面 链接 https pan baidu com s 1PuLYfZNf4stMKCh adv8zQ 提取码 z6ud 复制这段内容后打开百度网盘手机App 操作更方便哦 2 解压
  • 【JMeter03】登录接口解决方案

    个人站点 测试开发者https www devtester cn 1 解决验证码问题 在登录接口中 需要填写验证码 虽然是传统的图片型密码 可以尝试使用OCR方法识别 但对于接口测试 包括之后的UI测试 而言并不需要在验证码上大费周章 尤其
  • 毕业设计 - 基于Stm32的家庭智能监控系统 - 单片机 图像识别 人体检测 AI

    hr style border solid width 100px height 1px color 000000 size 1 quot 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到
  • 慕课网实战项目《WebAPP书城整站开发》笔记六:字体面板中“背景”切换的交互开发

    推荐IMOOC实战课程 WebApp书城整站开发 效果图 任务分解描述 本效果需要实现的是图中点击字体按钮后弹出一个可以设置字体颜色和大小的面板 点击面板上的 大 和 小 可以设置字体的大小 已完成 点击面板上的颜色圆圈可以切换阅读器的背景
  • Altium Designer常见问题整理(持续更新)

    Altium Designer DRC检查报告无法定位PCB具体错误位置 在AD中使用设计规则检查DRC 出具的PCB报告点击错误信息无法定位到具体错误位置 使用AD内置打开和浏览器打开均无效 原因 原理图与PCB工程文件存放路径存在中文导
  • python3.8安装tensorflow_python安装TensorFlow吐血整理

    1 安装特定版本的TensorFlow 1 pip install tensorflow gpu 1 9 0 2 pip install tensorflow gpu 必须用命令 1 才能安装想要的新版本 命令 2 只会安装TensorFl
  • element upload上传单张图片,效果同多图

    效果如图
  • MySQL多表查询

    目录 1 创建class数据库 2 创建student和score表 3 向student表插入记录的INSERT语句 4 向score表插入记录的INSERT语句 5 查询student表的所有记录 6 查询student表的第2条到4条
  • 使用命令行打开vscode

    vscode 最新版的vscode不需要配置 打开命令行工具 cmdr git 进入项目目录 输入下面命令 code 创建test js文件 code test js 旧版本需要配置一下 手动打开vscode ctrl shift p 打开
  • 总结了大佬的学习方法 #CSDN博文精选# #学习方法# #高效系统化学习#

    大家好 我是小C 全名是CSDN高校俱乐部 我的职责之一是担任 文章过滤器 精选大咖干货 助力学习之路 你是否曾面对海量信息而无从下手 你是否曾苦恼学习效果不佳 事倍功半 你是否曾感叹知识零碎而无法发挥用途 针对这些问题 小C将开启一个全新
  • vue使用mock模拟后台接口返回数据

    一 项目引入mock依赖 npm install mockjs save 或 cnpm install mockjs save 二 准备数据文件和模拟接口的文件 1 src 文件夹下新建 mock 文件夹 2 在 mock 文件夹下新建 m
  • spring源码阅读一:spring初始化容器时扫描package的过程

    注 spring version 4 2 0 RELEASE 首先 spring 管理注解bean容器主要是 AnnotationConfigApplicationContext org springframework context an
  • 解析Qt的ui_*.h文件

    mainwindow h常见的几行 namespace Ui class MainWindow private Ui MainWindow ui mainwindow cpp常见的几行 include ui mainwindow h Mai
  • MQTT协议实现Eclipse Paho学习总结一

    http blog csdn net yangzl2008 article details 8861069 一 概述 遥测传输 MQTT 是轻量级基于代理的发布 订阅的消息传输协议 设计思想是开放 简单 轻量 易于实现 这些特点使它适用于受
  • C++继承,语法+案例,超详细!!

    类的继承 继承是代码重用的一种方法 通过继承创建的新类称为 派生类 或 子类 被继承的类称为 基类 或 父类 继承即子类无需重新编写父类成员代码的情况下继承父类所有的成员 子类只需书写新增成员的代码 语法 class 子类名 继承方式 父类