当前位置: 首页 > news >正文

【C++进阶学习】第一弹——继承(上)——探索代码复用的乐趣

前言:

在前面,我们已经将C++的初阶部分全部讲完了,包括类与对象、STL、栈和队列等众多内容,今天我们就进入C++进阶部分的学习,今天先来学习第一弹——继承

目录

一、什么是继承?为什么会有继承?

二、继承的基本概念

2.1 继承的定义

2.2 继承关系和访问限定符

2.3 继承方式所带来的权限问题

三、基类和派生类的赋值转换

四、总结


一、什么是继承?为什么会有继承?

所谓继承,其实就是对代码复用的一种手段,通过一个已经存在的类来建立一个新类,并简化代码,比如当我们创建一个教师类和一个学生类的时候,他们所包含的信息分别是:学生:姓名、年龄、学号,老师:姓名、年龄、工号。

对于这样两个类,他们所包含的信息有很高的重合度,如果我们写两个类来包含各自的信息,就会显得比较冗余,尤其当我们的代码量很大的时候,如何来复用代码,对于我们简化代码就很重要。下面我们通过上面所说的教师类和学生类来引出我们的继承!

不用继承:

#include<iostream>
#include<string>
using namespace std;
class Teacher    //教师类
{
public:void print(){cout << _name << endl;cout << _age << endl;}
private:string _name = "zhangsan";    //名字int _age = 20;   //年龄string _jobid;   //工号
};
class student
{
public:void print(){cout << _name << endl;cout << _age << endl;}
private:string _name = "zhangsan";    //名字int _age = 20;   //年龄string _jobid;   //学号
};
int main()
{Teacher t;student s;t.print();s.print();return 0;
}

我们会发现这样的一段代码非常冗余,相同的成员变量和成员函数却要写两次,接下来我们就通过继承来简化这段代码

继承:

#include<iostream>
#include<string>
using namespace std;
class Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}
protected:string _name = "peter"; // 姓名int _age = 18;  //年龄
};class Student : public Person   
{
protected:int _stuid; // 学号
};
class Teacher : public Person
{
protected:int _jobid; // 工号
};
int main()
{Student s;Teacher t;s.Print();t.Print();return 0;
}

二、继承的基本概念

2.1 继承的定义

上面我们定义的Person类为父类,student和teacher类都是基类

2.2 继承关系和访问限定符

2.3 继承方式所带来的权限问题

描述:

上面所说的不可见其实就是不能直接访问的意思,通过上面的表格我们可以得到一个规律:派生类的权限大小取决于父类中成员的开放程度和继承方式,并且是以两者中权限小的为准

三、基类和派生类的赋值转换

基类和派生类有一个挺重要的问题就是互相之间的赋值转换,因为两者之间相似点还是很多的,所以他们两个之间是否可以相互转换呢?

答案是:派生类可以赋值给基类,但是基类不能赋值给派生类

派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用 。这里有个形象的说法叫切片
或者切割。寓意把派生类中父类那部分切来赋值过去。

如图所示:

下面我们给出赋值各种情况的代码,建议仔细阅读一下:

#include<iostream>
#include<string>
using namespace std;
class Person
{
protected:string _name; // 姓名string _sex;  //性别int _age; // 年龄
};
class Student : public Person
{
public:int _No; // 学号
};
void Test()
{Student sobj;// 1.子类对象可以赋值给父类对象/指针/引用Person pobj = sobj;Person* pp = &sobj;Person& rp = sobj;//2.基类对象不能赋值给派生类对象sobj = pobj;// 3.基类的指针可以通过强制类型转换赋值给派生类的指针pp = &sobj;Student * ps1 = (Student*)pp; // 这种情况转换时可以的。ps1->_No = 10;pp = &pobj;Student* ps2 = (Student*)pp; // 这种情况转换时虽然可以,但是会存在越界访问的问//题ps2->_No = 10;  //这就是越界访问的情况
}

四、总结

上面只是简单的讲了一下C++继承的一些知识,由于我们近期考试周的缘故,暂时就先写这么多了,下一篇我们将详细地介绍继承中一些更难的问题,比如多继承,菱形继承等问题,今天的文章就先到这了,感谢观看

感谢各位大佬观看,创作不易,还请各位大佬点赞支持一下下呀!!!

相关文章:

  • 6.14作业
  • 【Ardiuno】实验ESP32单片机自动配置Wifi功能(图文)
  • Solr7.4.0报错org.apache.solr.common.SolrException
  • 3、matlab单目相机标定原理、流程及实验
  • Linux2(文件类型分类 基本命令2 重定向)
  • 英伟达算法岗面试,问的贼专业。。。
  • 干货!电脑如何录屏?6款win10录屏大师软件深度测评
  • ElasticSearch的桶聚合
  • 如何基于 Python 快速搭建 QQ 开放平台 QQ 群官方机器人详细教程(更新中)
  • 学了这篇面试经,轻松收割网络安全的offer
  • 主流后端开发语言对比
  • linux 网桥学习
  • 多视图变换矩阵与SLAM位姿估计中的地图点投影的几何约束
  • oracle 删除当前用户下所有表
  • 2001-2023年上市公司数字化转型测算数据(含原始数据+处理代码+计算结果)
  • JS 中的深拷贝与浅拷贝
  • 分享一款快速APP功能测试工具
  • [译] 怎样写一个基础的编译器
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • es的写入过程
  • Git 使用集
  • leetcode386. Lexicographical Numbers
  • Web Storage相关
  • 理清楚Vue的结构
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 前言-如何学习区块链
  • 区块链将重新定义世界
  • 硬币翻转问题,区间操作
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ​【数据结构与算法】冒泡排序:简单易懂的排序算法解析
  • ​secrets --- 生成管理密码的安全随机数​
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • $.ajax中的eval及dataType
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
  • (Java入门)抽象类,接口,内部类
  • (八)c52学习之旅-中断实验
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (代码示例)使用setTimeout来延迟加载JS脚本文件
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (十六)、把镜像推送到私有化 Docker 仓库
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (四)Android布局类型(线性布局LinearLayout)
  • (一)Java算法:二分查找
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • *** 2003
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .Net Core 笔试1
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .netcore 获取appsettings
  • .net连接MySQL的方法