C++之继承<1>【详解】

news2025/1/24 17:35:18

C++之继承【详解】

  • 1. 继承的概念
  • 2. 继承定义的格式
    • 2.1 继承方式和访问限定符
    • 2.2 继承了基类成员后随着访问方式变化的变化
  • 3. 基类和派生类对象的复制转换
  • 5. 隐藏

1. 继承的概念

  继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。

  通俗意义上来理解,继承就像是传统习俗一样,子女会继承父母的一些特征,财产等等,一个人在刚刚出世的时候你不能指望他像他父母一样拥有工作的能力去帮助你完成某些事情,如果让你来培养他直到能够达到工作能力以后,可想而知需要花费多大的力气。就像计算机世界一样,你想快速轻松的获得一个具备完成某项任务的对象,但又不想花费精力编写一些重复的代码,这时候就可以用到继承。
  比如你想编写两个类分别是:学生类和老师类,编写其中的属性的时候发现,两个类中都有一些相同的属性,比如:姓名,性别,年龄,或者相同的行为,比如:吃饭,运动。两个类中都写的话显得冗余,就可以将其中相同的属性和行为提取出来,放入一个person类中,并且令学生类和老师类继承person类,这时学生类和老师类中可以不用写出这些属性和行为但是都分别拥有它们。其中,学生类和老师类叫做子类或者派生类,person类叫作父类或者基类。
  下面是代码体现:

#define _CRT_SECURE_NO_WARNINGS
#include <string>
#include <stdio.h>
class person
{
public:
	std::string name;
	int age;
	int gender;

	void sport()
	{
		printf("运动。。。\n");
	}

	void eat()
	{
		printf("吃饭。。。\n");
	}
};

class student : public person
{

};

class teacher : public person
{

};

int main()
{
	student st;
	st.sport();
	return 0;
}

在这里插入图片描述

  可以看到即使student类中没有编写任何代码,但是实际上已经继承了person的属性和行为。

2. 继承定义的格式

在这里插入图片描述

2.1 继承方式和访问限定符

  • 继承方式
    1. public继承
    2. protected继承
    3. private继承
  • 访问限定符
    1. public访问
    2. protected访问
    3. private访问

2.2 继承了基类成员后随着访问方式变化的变化

在这里插入图片描述
 理解上面的这张图:
   1. 基类中的private成员无论是什么继承方式,继承以后在派生类中都不可见。
      1.1这里的不可见只是派生类对象无论在类里面还是类外面都无法访问它,但是基类中的private成员还是继承到了派生类中,只是“不可见”。

   2. 基类中的其他成员继承后在派生类中的访问方式=Min(成员在基类中的访问方式,继承方式)

   3. protected就是为了继承而生的。当基类中的成员继承后不想被类外被访问但是想在类中可以访问,可以将这个基类成员设置为protected修饰,或者使用protected继承方式(但是使用protected继承后可能会将一些不希望设置为protected的public基类成员变成protected)。

   4. 使用关键字class时默认的继承方式是private,使用关键字struct时默认的继承方式是public,也就是说可以不用显式的写出继承方式,但是最好还是显示的写出来。

class person
{
public:
	std::string name;
	int age = 23;
	int gender;

	void sport()
	{
		printf("运动。。。\n");
	}

	void eat()
	{
		printf("吃饭。。。\n");
	}
};

class student :  person
{
public:
	void getAge()
	{
		printf("studentAge : %d\n", age);
	}
};

int main()
{
	student st;
	st.getAge();
	return 0;
}

在这里插入图片描述

   5. 在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里面使用,实际中扩展维护性不强。

3. 基类和派生类对象的复制转换

  • 派生类对象可以赋值给基类的对象 / 基类的指针 / 基类的引用。这个操作叫做切片或者切割。也就可以形象的看作是将派生类中属于基类中的那部分属性和行为“切割”出来赋值给基类。
    在这里插入图片描述
    红色的部分就是基类person和派生类student共有的属性,黄色的部分是派生类继承后声明的变量,只属于派生类student。

  • 基类对象不能赋值给派生类对象。

  • 基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用,但是必须是基类的指针指向派生类对象时才是安全的。

class person
{
public:
	std::string name;
	int age = 23;
	int gender;

	void sport()
	{
		printf("运动。。。\n");
	}

	void eat()
	{
		printf("吃饭。。。\n");
	}
};

class student : public person
{
public:
	int study() 
	{ 
		
		printf("学生在学习。。。\n");
	}

	
	
};

int main()
{
	student st;
	
	//派生类对象可以赋值给基类的对象 / 基类的指针 / 基类的引用
	person ps = st;
	person* ps_ptr = &st;
	person& rps = st;

	//基类对象不能赋值给派生类对象。
	person pss;
	st = pss;

	//基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用,
	//但是必须是基类的指针指向派生类对象时才是安全的。
	person* pss_ptr = &st;
	student* pst = (student*)pss_ptr;

	//虽然不会报错,但是存在越界访问的问题。
	person pps;
	person* pps_ptr = &pps;
	student* ppst = (student*)pps_ptr;

	return 0;
}

5. 隐藏

  1. 在继承体系中基类和派生类都有独立的作用域。
  2. 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏, 也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)
  3. 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。
  4. 注意在实际中在继承体系里面最好不要定义同名的成员。
  • 区别隐藏和重载: 隐藏是作用于两个作用域的,重载是作用域一个作用域的。
class person
{
public:
	std::string name;
	int age = 23;
	int gender;

	void sport()
	{
		printf("运动。。。\n");
	}
};

class student :  person
{
public:
	void getAge()
	{
		printf("studentAge : %d\n", age);
	}

	int age = 87;
};

int main()
{
	student st;
	st.getAge();//输出结果是87
	return 0;
}

在这里插入图片描述


class person
{
public:
	std::string name;
	int age = 23;
	int gender;

	void sport()
	{
		printf("运动。。。\n");
	}

};

class student : person
{
public:
	int sport(int n)
	{
		printf("打篮球。。。\n");
		return n;
	}
};

int main()
{
	student st;
	st.sport(34);//输出结果是87
	return 0;
}

在这里插入图片描述
上面代码说明,对于成员函数,只要函数名相同就构成隐藏。

  😄 创作不易,你的点赞和关注都是对我莫大的鼓励,再次感谢您的观看😄

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

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

相关文章

日志分析题目

关卡描述&#xff1a;1、黑客在内网抓了两台肉鸡对服务器进行攻击&#xff0c;请给出两台肉鸡的IP&#xff08;使用空格分隔&#xff09; 直接查看日志 rh 然后ls&#xff0c;查看 这里我没有看到明显web容器的字样&#xff0c;例如apache&#xff0c;iis的等等。 就看容器…

《华为战略管理法:DSTE实战体系》作者谢宁老师受邀为某电力上市集团提供两天的《成功的产品管理及产品经理》内训。

​​ 近日&#xff0c;《华为战略管理法&#xff1a;DSTE实战体系》作者谢宁老师受邀为某电力上市集团提供两天的《成功的产品管理及产品经理》内训。 谢宁老师作为华为培训管理部特聘资深讲师和顾问&#xff0c;也是畅销书《华为战略管理法&#xff1a;DSTE实战体系》、《智慧…

贪心算法(一)

&#x1f58a;作者 : D. Star. &#x1f4d8;专栏 : 算法小能手 &#x1f606;今日提问 : 国庆去哪里打卡了呢&#xff1f; &#x1f606;今日分享 : 武功山风景打卡–双云海 文章目录 &#x1f33b;贪心算法的思想&#x1f33b;贪心算法的基本思路&#x1f4d6;给大家讲一个小…

高可用eureka服务注册与发现代码例子

代码 Eureka server 1 pom.xml <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.clou…

Python开源项目周排行 2023年第36周

#2023年第36周2023年10月14日1书生・浦语灵笔图文混合创作大模型。基于书生・浦语大语言模型研发的视觉 - 语言大模型&#xff0c;提供出色的图文理解和创作能力&#xff0c;具有多项优势&#xff1a; 图文交错创作: 浦语・灵笔可以为用户打造图文并貌的专属文章。生成的文章文…

Go语言入门心法(五): 函数

一: go语言函数认知 Go语言入门心法(一): 基础语法 Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 忙着去耍帅,后期补上..........

从不同的正态分布中抽取随机数randn()函数

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 从不同的正态分布中抽取随机数 randn()函数 [太阳]选择题 下列选项对代码最后运行结果描述错误的是&#xff1f; import numpy as np print("【执行】np.random.randn()") print(np.…

《UnityShader入门精要》学习5

Unity中的基础光照 从宏观上来说&#xff0c;渲染包含了两大部分&#xff1a;决定一个像素的可见性&#xff0c;决定这个像素上的光照计算 我们是如何看到这个世界的 通常来讲&#xff0c;我们要模拟真实的光照环境来生成一张图像&#xff0c;需要考虑3种物理现象。 首先&a…

13年测试老鸟总结,真实性能测试如何做?性能测试完整流程+细节...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试什么时候…

【HttpRunner】接口自动化测试框架

简介 2018年python开发者大会上&#xff0c;了解到HttpRuuner开源自动化测试框架&#xff0c;采用YAML/JSON格式管理用例&#xff0c;能录制和转换生成用例功能&#xff0c;充分做到用例与测试代码分离&#xff0c;相比excel维护测试场景数据更加简洁。在此&#xff0c;利用业…

傅里叶变换和其图像处理中的应用

以下部分文字资料整合于网络&#xff0c;本文仅供自己学习用&#xff01; 一、为什么要在频域进行图像处理&#xff1f; 一些在空间域表述困难的增强任务&#xff0c;在频率域中变得非常普通 滤波在频率域更为直观&#xff0c;你想想嘛&#xff0c;所谓滤波&#xff0c;就是…

第 115 场 LeetCode 双周赛题解

A 上一个遍历的整数 模拟 class Solution { public:vector<int> lastVisitedIntegers(vector<string> &words) {vector<int> res;vector<int> li;for (int i 0, n words.size(); i < n;) {if (words[i] ! "prev")li.push_back(stoi…

数据结构与算法——线性查找法

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

冲刺十五届蓝桥杯P0005单词分析

文章目录 题目分析代码 题目 单词分析 分析 统计字符串中字母出现的次数&#xff0c;可以采用哈希表&#xff0c;代码采用的是数组来存储字符&#xff0c;将字符-97&#xff0c;得到对应的数组下标&#xff0c;将对应下标的数组&#xff1b;找到数组元素最大的下标&#xff…

微店店铺所有商品数据接口,微店整店商品数据接口,微店店铺商品数据接口,微店API接口

微店店铺所有商品数据接口是一种允许开发者在其应用程序中调用微店店铺所有商品数据的API接口。利用这一接口&#xff0c;开发者可以获取微店店铺的所有商品信息&#xff0c;包括商品名称、价格、介绍、图片等。 其主要用途是帮助开发者进行各种业务场景的构建&#xff0c;例如…

如果不封车,坚持冬天骑行应该注意些什么?

亲爱的骑行爱好者们&#xff0c;你们好&#xff01;随着秋天的脚步渐行渐远&#xff0c;冬天也不远了。对于热爱骑行的你们来说&#xff0c;秋天的骑行是一种享受&#xff0c;而冬天的骑行则是一种挑战。那么&#xff0c;如果你打算在秋天骑行不封车&#xff0c;坚持过冬天&…

小解C语言文件编译过程【linux】

小解C语言文件编译过程【linux】 库动态库静态库 C语言文件 程序编译过程整体预处理编译汇编链接动态链接静态链接两种方法对比 库 看到标题是文件编译过程 但是开头却是库&#xff0c;这可不是挂羊头卖狗肉&#xff0c;而是因为库也是代码不可缺少的一部分&#xff0c;并且在…

运维 | 如何查看端口或程序占用情况 | linux

运维 | 如何查看端口或程序占用情况 | linux 前言 本期主要介绍了 LINUX 中如何查看某个端口或程序的使用情况&#xff0c;希望对大家有所帮助。 快速使用 netstat 命令&#xff08;推荐&#xff09; netstat 命令可以显示网络连接、路由表和网络接口信息等。可以使用 net…

股票量化分析工具QTYX使用攻略——代号“飞龙在天”,狙击龙头股战法(更新2.7.1)...

搭建自己的量化系统 股票量化交易系统QTYX是一个即可以用于学习&#xff0c;也可以用于实战炒股分析的系统。 分享QTYX系统目的是提供给大家一个搭建量化系统的模版&#xff0c;最终帮助大家搭建属于自己的系统。因此我们提供源码&#xff0c;可以根据自己的风格二次开发。 关于…

芯片学习记录LM2596

LM2596 芯片介绍 LM2596 系列稳压器是为降压开关稳压器提供所有有效 功能的单片集成电路&#xff0c; 能够驱动 3A 的负载 &#xff0c; 并且拥有 出色的线路和负载调节性能。这些器件可提供 3.3V 、 5V、 12V 固定输出电压和可调节输出电压版本。 这类稳压器不仅需要很少的…