C++类的继承(听课笔记)

代码1: 子类访问限定、继承方式 ,以及 子类和父类复制兼容
#include<iostream>
using namespace std;//父类和子类是两个独立的作用域
//所以他的属性和方法可以重名class Person//父类
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}
protected:string _name = "peter";
public:int _age = 18;//private成员在子类中不能直接访问//但可以间接获取,例如 Get
};class Student :protected Person//子类 继承方式
{
protected:int _stuid;
};class Teacher :public Person
{
protected:int _jobid;
};// 父类为struct ,子类默认继承方式和访问限定符都是公有的
// 父类为class  ,子类默认继承方式和访问限定符都是私有的struct other :public Person//默认public
{//public
};int main()
{Student s;Teacher t;//s.Print();//public+protected = protected (在类外面不能访问)t.Print();// publuc+publicPerson p = t;//Person p = s;  protected 不能访问//子类可以直接赋值给父类,但是受限制,只有子类的 成员或函数 是 公有public才能//每个子类对象都是一个特殊的父类对象//父类=子类 --> 切割/切片Person& ref = t;//赋值兼容: 不产生临时变量,不用加 const 修饰// ref 就是直接指向切片部分ref._age = 19;//ref可以修改子类(但限制为 public) return 0;
}
代码2: 父类和子类的显示构造函数、构造顺序、析构顺序
#include<iostream>
using namespace std;class Person
{
public:Person(const char* name): _name(name){cout << "Person()" << endl;}Person(const Person& p):_name(p._name){cout << "Person(const Person& p)" << endl;}Person& operator=(const Person& p){cout << "Person& operator=(const Person& p)" << endl;if (this != &p)_name = p._name;return *this;}~Person(){cout << "~Person()" << endl;}
protected:string _name = "peter";
};class Student : public Person
{
public:// 1.如果 子类没有默认构造函数,并且父类也没有默认构造函数,那么在子类的构造函数中必须 显式调用 父类的特定构造函数,否则编译器会报错。// 2.若 子类的构造函数中没有 显式调用 父类的 特定构造函数,那么父类会调用 本身的构造函数 ,若父类没有默认构造函数,否则编译器会报错。Student(const char* Pname, const char* Sname):Person(Pname)//显示调用父类构造函数, _name(Sname){cout << "Student()" << endl;}//Student(const Student& s)   不存在深拷贝时,拷贝构造可以不用写Student(const Student& s):Person(s)//子类可以赋值给父类, _name(s._name){cout << "Student(const Student& s)" << endl;}Student& operator=(const Student& s){cout << "Student& operator=(const Student& s)" << endl;if (this != &s){Person::operator=(s);//和父类重名,父类函数隐藏_name = s._name;}return *this;}~Student(){// ~Person();  此处又不能显示调用// 子类的析构也会隐藏// 因为后期多态,析构函数都会被统一处理成 destructor,导致函数重名// Person::~Person();//即使不写也会自动调用//写了就进行两次析构 (且析构顺序无法是先子类后父类//还是要指定作用域cout << "~Student()" << endl;;;}//构造: 先父类后子类//析构: 先子类后父类void Print(){cout << _name << endl;cout << Person::_name << endl;;//直接指定类域进行访问}
protected:string _name = "lihua";//属性可以重名// Person// 父类+自己,父类的调用父类构造函数初始化(复用)// 父类成员当成一个整体的自定义成员
};int main()
{Student s1("zhangsan", "lisi");//父类 子类s1.Print();//Person()  Student()  lisi  zhangsan//当子类和父类属性重名(只看名称),优先访问当前类域(也称隐藏)cout << endl;Student s2(s1);s2.Print();//Person(const Person& p)  Student(const Student & s)  lisi zhangsan 拷贝构造cout << endl;Student s3("wangwu", "zhaoliu");s3.Print();// Person()  Student()  构造 + 构造cout << endl;Student s4 = s3;s4.Print();//Person(const Person& p)  Student(const Student & s)  拷贝构造cout << endl;Person p("zz");//p.~Person();//显示调用 Person 的析构函数,多次析构return 0;
}
代码3: 类中 静态成员的归属
#include<iostream>
using namespace std;
class Student;
class Person
{
public:Person(){_count++;//可以通过静态成员来计算创建成员个数}friend void Display(const Person& p, const Student& s);//友元不能继承
protected:string _name;
public:static int _count;//静态成员只有一份,子类和父类共用//父类静态成员属于当前类,也属于当前类的所有类
};
int Person::_count = 0;class Student : public Person
{friend void Display(const Person& p, const Student& s);
protected:int _stuNum;//Student 中
};void Display(const Person& p, const Student& s)
{cout << p._name << endl;cout << s._stuNum << endl;
}
int main()
{Person p;Student s;cout << &Person::_count << endl;cout << &Student::_count << endl;//公用一块空间return 0;
}
代码4: 菱形继承问题(虚继承)
//单继承/多继承(父类个数是否唯一
//菱形继承: 多继承的特殊情况(见图)
//问题:  1.数据冗余
//       2.二义性/*
#include<iostream>
using namespace std;class Person
{
public:string _name; // 姓名
};class Student : virtual public Person//虚继承(可有效解决菱形继承问题)
{
protected:int _num; //学号
};class Teacher : virtual public Person
{
protected:int _id; // 职工编号
};class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};void Test()
{// 这样会有二义性无法明确知道访问的是哪一个Assistant a;a._name = "peter";//Student类和Teacher类都有_name// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}int main()
{Test();return 0;
}

以上是关于类的基本定义和基本实现,关于虚函数,可以看我下一篇博客!!!

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

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

相关文章

JVM-类加载机制

一、基础概念 当我们用java命令运行某个类的main函数启动程序时&#xff0c;首先需要通过类加载器把该类加载到JVM。 其主要流程如下&#xff1a; 1.什么是类加载 那么什么是类加载&#xff1f; Java的类加载&#xff0c;就是把字节码格式“.class”文件加载到JVM的方法区…

48、基于深度学习的离群值输入向量(matlab)

1、基于深度学习的离群值输入向量原理及流程 基于深度学习的离群值检测的输入向量原理是通过神经网络模型对数据进行学习和表示&#xff0c;在该表示中探测异常样本。其流程大致如下&#xff1a; 数据预处理&#xff1a;将数据进行归一化处理&#xff0c;确保神经网络模型能够…

pycharm常用快捷键

详细总结了Pycharm的常用快捷键&#xff0c;下文介绍使用方法和场景, 并不需要记忆这些快捷键, 你只需要知道有这些快捷键, 再需要用的时候查看一下, 用的多了自然也就记住了,需要的朋友可以参考下 1.注释(添加/消除)(Ctrl /)这里说下Python的单行注释是 # , 多行注释是 注释内…

L59---101.对称二叉树(广搜)---Java版

1.题目描述 2.思路和知识点 &#xff08;1)根节点为空&#xff1a; 如果根节点为空&#xff0c;树是对称的。 (2)递归检查&#xff1a; isMirror 方法递归检查两个子树是否是镜像对称的。 (3)辅助函数 isMirror&#xff1a; 1)如果两个节点都为空&#xff0c;它们是镜像对称的…

react笔记-04redux篇

redux和react-redux笔记&#xff0c;以及项目中如何使用&#xff0c;对redux的封装&#xff0c;让其使用类似于vuex一样方便。 一、redux 1. redux工作流程 流程&#xff1a;创建action > dispatch分发action > 交给store > reducer加工数据返回给store 2. redux的…

LabVIEW在核磁共振实验室的应用

​核磁共振&#xff08;NMR&#xff09;实验室在进行复杂的核磁共振实验时&#xff0c;需要一个高效、灵活且易于操作的实验控制和数据采集系统。传统的NMR实验系统往往使用专门的硬件和软件&#xff0c;存在系统封闭、扩展性差、维护成本高等问题。为了解决这些问题&#xff0…

揭秘Redis中的高级数据结构:跳跃表Skiplist

Redis数据结构-跳跃表Skiplist 1. 简介1.1. Redis高性能键值存储数据库1.2. Redis的特点和优势1.3. 跳跃表Skiplist 2. 跳跃表的概念和背景2.1 跳跃表的概念2.2 跳跃表的发展历程和提出背景 3. 跳跃表的基本原理3.1 结构概述3.1.1 跳跃表的结构概述3.1.2 跳跃表的节点结构 3.2 …

Stable Diffusion【进阶篇】:真人漫改之迪士尼风格定制

大家好&#xff0c;我是极客菌 关于真人漫改是一个应用比较多的图片定制方向&#xff0c;本文以及后面的章节我们结合一些具体的大模型或者LORA来更深入的实践一下。 一. 迪士尼风格 在SD的大模型中&#xff0c;实现迪士尼或者皮卡斯风格的图片&#xff0c;首推 Disney Pix…

从零开始构建CNN模型

猫狗分类问题——从零开始构建CNN 我们将使用相同的体系结构&#xff0c;并进行一些小的更改&#xff0c;如下所示。 第一个线性层的输入尺寸发生变化&#xff0c;因为猫和狗的图像尺寸是(256,256)。添加了另一个线性层来为模型学习提供更多的灵活性。 让我们来看看实现网络架…

Java中的函数式编程指南

Java中的函数式编程指南 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 随着Java 8的发布&#xff0c;Java引入了函数式编程的概念&#xff0c;使得代码更简洁…

Unity资源加密方案

在 Unity 项目中&#xff0c;为了保护资源&#xff08;如纹理、音频、模型和脚本等&#xff09;免受未经授权的访问和盗用&#xff0c;可以采用多种加密和保护方案。以下是几种常见的 Unity 资源加密方案&#xff1a; 一. 加密和解密资源文件 常见的加密算法有 AES、RSA 等。…

CesiumJS【Basic】- #012添加点线面(entity方式)

文章目录 添加点线面(entity方式)1 目标2 实现2.1 GeometryManager.ts2.2 main.ts添加点线面(entity方式) 1 目标 使用实体方式添加点线面 2 实现 2.1 GeometryManager.ts // src/GeometryManager.tsimport * as Cesium from cesium;export class GeometryManager {pr…

带你学习PID控制算法

#PID涉及相关知识 开环控制系统&#xff1a;开环系统&#xff0c;无反馈系统&#xff0c;即系统的输入不受输出的影响&#xff0c;在受到外界干扰输出效果减小&#xff0c;此时输入也不会增加&#xff0c;因为输出不会对输入施加影响&#xff0c;像是断开的环一样称为开环&…

二自由度机械臂软件系统(一)urdf和moveit2

一、urdf模型 参考链接&#xff1a;https://blog.csdn.net/weixin_45168199/article/details/105755388 这部分直接看参考链接就可以&#xff0c;主要思路如下 1、把sw中的零散零件按照机器人中连杆的分类整合成几个大零件 2、把几个大零件整合成装配体&#xff0c;并设置若干…

eNSP中静态NAT和动态NAT的配置和使用

一、静态NAT 1.拓扑图 a.新建拓扑图 b.PC端配置 PC1: PC2&#xff1a; c.路由器配置 AR1: <Huawei>system-view [Huawei]sysname R1 [R1]interface GigabitEthernet 0/0/0 [R1-GigabitEthernet0/0/0]ip address 192.168.1.254 24 [R1-GigabitEthernet0/0/0]quit…

Redis数据结构—跳跃表 skiplist

一、引言 在数据库和缓存系统的世界中&#xff0c;Redis以其高性能、高可用性、丰富的数据结构以及简洁的API而备受青睐。Redis支持多种数据结构&#xff0c;包括字符串、列表、集合、有序集合等&#xff0c;每种数据结构都对应着一种或多种内部实现。其中&#xff0c;跳跃表&…

TDengine 签约精诚瑞宝,开拓更智能的 IT 服务和管理平台

在当今的数字化时代&#xff0c;数据不仅是企业运营的核心资产&#xff0c;更是推动业务创新和服务优化的关键驱动力。随着数据量的激增&#xff0c;企业面临的挑战也随之增加&#xff0c;尤其是在数据处理和分析的效率上。作为台湾信息服务产业领导厂商精诚集团的核心成员&…

昇思25天学习打卡营第2天|linchenfengxue

传统的计算机视觉方法通常包括图像预处理、特征提取、特征筛选、图像识别等几个步骤。 对于给定的数字图像&#xff0c;计算机在处理时要先执行二次采样、平滑去噪、对比度提升和尺度调整等预处理操作&#xff0c;再对图像中的线条、边缘等全局特征和边角、斑点等局部特征&…

嵌入式信号处理面试题及参考答案(持续更新)

什么是离散时间信号?与连续时间信号的主要区别是什么? 离散时间信号是一种仅在离散时间点上有定义的信号,它不连续存在于所有时间点上,而是只在特定的、通常是均匀间隔的时间点取值。这种信号的表示通常通过序列来完成,比如在数字信号处理中广泛应用的各种音频、视频或控…

MySQL 性能优化全面指南

MySQL 性能优化全面指南 优化MySQL性能是提升数据库响应速度、降低延迟和提高系统整体性能的关键。以下是一些常用的MySQL性能优化方法&#xff0c;涵盖了硬件、配置、查询、索引、架构等多个方面。 1. 硬件优化 1.1. 增加内存 确保有足够的内存来缓存索引和数据&#xff0…