继承初级入门复习

注意:保护和私有在类中没有区别,但是在继承中有区别,private在继承的子类不可见,protect在继承的子类可见 

记忆方法:先看基类的修饰符是private,那都是不可见的。如果不是,那就用继承的修饰和基类的修饰比较谁小取谁----->public>protect>private

#include <iostream>
using namespace std;
class Person
{
protected:string _name;string _sex;int _age;
};
class Student :public Person
{
public:int _No;
};
int main()
{Person p;Student s;//子类和父类之间赋值兼容规则//1、子类对象可以赋值父类对象/指针/引用p = s;Person* p1 = &s;Person& p1 =  s;return 0;
}

注意:父类不可以赋值给子类,有一种情况就是父类指向子类,再赋值给另一个子类

不同作用域(隐藏(重定义))

class Person
{
protected:string _sex;int _age=111;
};
class Student :public Person
{
public:void f(){cout << _age << endl;}
public:int _age=99;
};
int main()
{Student s;s.f();
}

面向对象的三大特性

封装(类的封装)、继承、多态

实际上面向对象不只三大特性

派生类的默认成员函数

注意:如果是自定义类型就会调用自己的默认构造函数(struct  class)

如何在子类中初始化父类部分呢?

class Person
{
public:Person(const char* name):_name(name){cout << "Person()" << _name<< endl;}~Person(){cout << "~Person()" << endl;}
private:string _name;
};
class Student : public Person
{
public:Student(const char* name,int age)//所以要加const这个块空间是只读:Person(name),_stuid(age){}
protected:int _stuid;
};
int main()
{Student a("joker",1);//传入常量字符串return 0;
}

父类继承部分一定要调用父类去完成,如果不显示调用的话也会自动调用父类的构造函数

假设1:

默认构造函数包括无参、全缺省、系统默认生成的

如果是系统调用的默认构造函数内置类型是不会处理的,只有自定义类型才会处理

假设2:

如何完成子类拷贝构造呢?

什么是拷贝构造?

1、拷贝构造的参数只有一个,该参数的类型是对象类型的引用,为什么要引用?因为防止无限的调用拷贝构造去递归,一般用const修饰

2、要区分深拷贝和浅拷贝的问题,系统默认生成的拷贝函数的内存存储方式是字节序存储所以要注意成员变量类型的,防止释放两次同一个空间

复习完成

class Person
{
public:Person(const char*name=""):_name(name){cout <<_name << "Person()" << endl;}Person(const Person& p1):_name(p1._name){cout << "Person(const Person& p1)" << endl;}
private:string _name;
};
class Student :Person
{
public:Student(const char*name,int id):Person(name),//要以父类名()的方式调用父类构造函数初始化子类中的父类部分_stuid(id){cout << "student()" << endl;}Student(const Student& s1):Person(s1)//要以父类名()的方式调用父类的拷贝构造函数  复制子类中的父类部分{_stuid = s1._stuid;cout << "Student(const Student& s1)" << endl;}
private:int _stuid;
};int main()
{//Person p1("aaa");Student s1("bbb",9);//初始化Student s2(s1);//拷贝构造//Student s3 ("gg",30);//初始化//s1 = s3;//s1.operator=(s3)return 0;
}

注意:只有显示的用父类(子类对象)的显示调用方式才可以调用父类的拷贝构造,系统不会自动调用父类的拷贝构造这个和初始化构造不一样

子类的operator=:

class Person
{
public:
//初始化Person(const char*name=""):_name(name){cout <<_name << "Person()" << endl;}
//拷贝Person(const Person& p1):_name(p1._name){cout << "Person(const Person& p1)" << endl;}
//父类的operator=函数Person& operator=(const Person& s1){if (this != &s1){_name = s1._name;cout << "Person& operator=(const Person& s1)" << endl;}return *this;}
private:string _name;//string(const char*s1)
};
class Student :Person
{
public:Student(const char*name,int id):Person(name),_stuid(id){cout << "student()" << endl;}Student(const Student& s1):Person(s1)//要以父类名()的方式调用父类的拷贝初始化子类中的父类部分{_stuid = s1._stuid;cout << "Student(const Student& s1)" << endl;}
//operator=Student& operator=(const Student& s1){if (this != &s1)//防止赋值时,两个对象时一个对象,浪费时间{Person::operator=(s1);//显示调用父类的operator=,将父类的部分赋值_stuid = s1._stuid;cout << "Student& operator=(const Student& s1)" << endl;}return *this;//返回子类的对象}
private:int _stuid;
};int main()
{//Person p1("aaa");Student s1("bbb",9);//初始化Student s2(s1);//拷贝构造//Student s3 ("gg",30);//初始化//s1 = s3;//s1.operator=(s3)return 0;
}

子类的析构函数 

注意:

1、子类的初始化时先父后子,所以析构就是先子后父,类似于stack

2、虽然父类的析构和子类的析构名字不相同,但是子类和父类的析构会被统一的处理成destructor构成隐藏

3、系统已经实现好当子类析构完成了,就会自动调用父类的析构

面试题

如何构建一个不可以继承的类

#include <iostream>
using namespace std;class A
{
private:   //将父类的初始化私有化A(){}
}
class B:public A
{}
int main()
{B b;//初始化不了对象return 0;
}

 友元关系不能被继承(了解就好)

会报错,要是想用只可以手动添加

静态成员在父类中被继承会发生什么?


class Person
{
public:Person(){_count++;}public:string _name;static int _count;
};int Person::_count = 0;//静态成员必须初始化class Student:public Person
{
public:
private:int id;
};int main()
{Person p1;Student s1; p1._name = "jack";s1._name = "rose";p1._count = 1;s1._count = 2;cout << Person::_count << endl;//静态成员属于对象也属于类所以可以Person::_countreturn 0;
}

static 成员属于对象也是属于类的,子类继承下来的静态成员和父类是一样的它们调用同一个静态成员变量

多继承

什么叫单继承:只有一个父类

所以多继承:就是有多个父类

多继承会造成很多问题的,所以后来的语言是没有多继承的,多继承是一个大坑

为什么是大坑?

因为多继承的一种特殊的继承菱形继承,会造成数据冗余和二义性

class Person
{
public:string _name; // 姓名
};
class Student : public Person
{
protected:int _num; //学号
};
class Teacher : public Person
{
protected:int _id; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};
void Test()
{// 这样会有二义性无法明确知道访问的是哪一个Assistant a;a._name = "peter";//菱形继承会导致二义性不知道是那个的_name// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}

菱形继承:

菱形继承原理

experiment:

class A
{
public:int _a;
};
class B:public A
{
public:int _b;
};
class C :public A
{
public:int _c;
};
class D:public B , public C
{
public:int _d;
};
int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}

进入调试看内存

这是内存模型,存在数据冗余和二义性

但是我们要看虚继承的内存模型

using namespace std;
class A
{
public:int _a;
};
class B:virtual public A//添加了virtual
{
public:int _b;
};
class C :virtual public A
{
public:int _c;
};
class D:public B , public C
{
public:int _d;
};
int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}

进入调试内存

接下来看看这些是什么?

好像是地址

再次进入内存

存在偏移量,存放偏移量的地方又叫虚基表

为什么要设计出来呢?

因为菱形继承会出现数据冗余和二义性,所以virtual继承是为了解决二义性和数据冗余

菱形继承:

虚继承:

为什么虚继承会比菱形继承还大呢?

是因为多了两个指针 

我相信很多同学会问不是解决数据冗余吗?为什么越来越大了

因为基类太小了

菱形继承:

虚继承:

少了一倍

这就是虚继承的基本概念

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

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

相关文章

gstreamer Windows常见问题汇总

需要先安装gstreamer , 再编译opencv。https://gstreamer.freedesktop.org/download/&#xff0c;都需要安装。 OpenCV Error: Unspecified error (The function is not implemented. Rebuild the library with Windows, GTK 2.x or Carbon support. If you are on Ubuntu or D…

肌肤暗沉与胶原蛋白:解锁透亮肌肤的秘密

&#x1f338;亲爱的小仙女们&#xff0c;今天我们来聊聊肌肤暗沉与胶原蛋白之间的神秘联系。你是不是也曾为肌肤的暗沉而烦恼&#xff1f;其实&#xff0c;很多时候&#xff0c;肌肤的暗沉不仅仅是外部因素造成的&#xff0c;更与肌肤内部的胶原蛋白含量密切相关。&#x1f31…

系统架构师-考试-基础题-错题集锦1

系统架构师-考试-基础题-错题集锦 1.当一台服务器出现故障时将业务迁移到另外一台物理服务器上&#xff0c;保障了业务的连续性。 2.面向对象&#xff1a; 实体类&#xff0c;边界类&#xff0c;控制类 3.RUP&#xff1a;UP&#xff0c;统一过程&#xff0c;以架构为中心&am…

LeetCode700二叉搜索树中的搜索

题目描述 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 null 。 解析 最基本的二叉搜索树的应用&#xff0c;递归或者while循环都可以…

分布式数据库HBase入门指南

目录 概述 HBase 的主要特点包括: HBase 的典型应用场景包括: 访问接口 1. Java API: 2. REST API: 3. Thrift API: 4. 其他访问接口: HBase 数据模型 概述 该模型具有以下特点&#xff1a; 1. 面向列: 2. 多维: 3. 稀疏: 数据存储: 数据访问: HBase 的数据模型…

炼丹学习笔记2---ubuntu2004运行3D Gaussian Splatting记录

前言 主要想看看前沿效果&#xff0c;看看跟激光slam出来效果差多少。折腾过程中&#xff0c;务必 根据本地的cuda版本号&#xff0c;安装对应的torch相关东西。 1、拉仓库 git clone https://github.com/graphdeco-inria/gaussian-splatting.git2、创建环境并激活 conda c…

MySQL详细安装、配置过程,多图,详解

本文适合centos7环境下安装mysql&#xff0c;在安装和卸载过程中&#xff0c;都在root用户下完成。文章目录 清理环境获取mysql官方yum源安装mysql yum源安装mysql服务安装报错解决办法验证是否安装完成启动mysql服务登录服务方法一&#xff1a;方法二&#xff1a;方法三&#…

数据意外删除?安卓手机数据恢复教程来帮你解救

手机不仅仅是一个通讯工具&#xff0c;更是我们记录生活、工作、学习等各种信息的重要载体&#xff0c;无论是拍照、录音、录像&#xff0c;还是文字记录&#xff0c;手机都能轻松完成。可有时候我们会不小心删除一些重要的数据&#xff0c;这时候我们该怎么办呢&#xff1f;别…

Modbus-RTU/TCP规约 | 报文解析 | 组织报文与解析报文(C++)

文章目录 一、MODBUS规约1.MODBUS-RTU规约2.MODBUS-TCP规约 二、报文解析1.MODBUS-RTU报文帧解析2.MODBUS-TCP报文帧解析 三、C代码实现组织报文与解析报文 一、MODBUS规约 Modbus规约是一种广泛使用的串行通信协议&#xff08;应用层报文传输协议&#xff09;&#xff0c;用于…

鲲泰新闻丨第七届数字中国建设峰会正式启幕,神州鲲泰携手天翼云共筑智算云生态

2024年5月23日&#xff0c;由国家发展改革委、国家数据局、国家网信办、科技部、国务院国资委、福建省人民政府共同主办的“第七届数字中国建设峰会”在福建省福州市海峡国际会展中心盛大开幕。 数字中国建设峰会是展示数字中国建设成就的盛会&#xff0c;本次峰会以“释放数据…

【MYSQL】分数排名

表: Scores ---------------------- | Column Name | Type | ---------------------- | id | int | | score | decimal | ---------------------- id 是该表的主键&#xff08;有不同值的列&#xff09;。 该表的每一行都包含了一场比赛的分数。Score 是…

草图大师2024怎么保存低版本呢?插件怎么写?

草图大师是一款流行的绘图和设计软件&#xff0c;为了向后兼容&#xff0c;保存低版本文件时&#xff0c;可以采取以下步骤&#xff1a; su模型库 1.另存为旧版本格式&#xff1a; 在保存文件时&#xff0c;草图大师通常会提供一个选项&#xff0c;让你选择要保存的文件格式和…

智简云携手云器Lakehouse打造一体化大数据平台,释放数据价值

导读 本篇分享的是智简云使用云器Lakehouse升级数据平台的实践总结。 智简云&#xff0c;是一家拥有十余年历史的科技公司&#xff0c;专注于企业服务领域&#xff0c;开发了两款核心产品&#xff1a;基于PASS平台的客户关系管理&#xff08;CRM&#xff09;系统和为中小型用…

Go微服务——go-micro v4安装使用

安装go-micro 打开cmd窗口&#xff0c;执行以下命令 go install github.com/go-micro/cli/cmd/go-microlatest测试是否成功安装 go-micro -v创建服务 go-micro new service helloworldwindows 安装make 安装地址 https://gnuwin32.sourceforge.net/packages/make.htm 配置…

springboot集成达梦数据库8,用springboot+mtbatisplus查询值为空

springboot集成达梦数据库8&#xff0c;用springbootmtbatisplus查询值为空 背景&#xff1a;springboot集成达梦数据库8&#xff0c;用springbootmtbatisplus查询值为空&#xff0c;但是在DB管理工具中是可以查询到数据的。 原因及解决方法&#xff1a;执行添加语句后&#xf…

《MySQL怎样运行的》—InnoDB数据页结构

在上一篇文章中我们讲了&#xff0c;InnoDB的数据页是InnoDB管理存储空间的基本单位&#xff0c;一个页的大小基本为16kb 那你有没有疑问&#xff0c;就是说这个InnoDB的数据页的结构是什么样的&#xff0c;还有他这些结构分别有那些功能~接下来我们一一讲解 数据页的总览结构…

Linux笔记之命令行JSON处理器jq

Linux笔记之命令行JSON处理器jq code review! 文章目录 Linux笔记之命令行JSON处理器jq1.安装2.jq 基本用法3.例程3.1. 示例JSON文件3.2. 读取特定字段3.3. 管道过滤器&#xff08;Pipe Filters&#xff09;3.4. 映射过滤器&#xff08;Map Filters&#xff09;3.5. 条件过滤…

自动化重置数据库功能的探索与实践

1、简介 在现代软件开发中&#xff0c;尤其是涉及到数据驱动的应用程序时&#xff0c;开发和测试环境中数据库的管理是至关重要的一环。为了确保开发和测试环境中的数据库始终处于一致的状态&#xff0c;自动化重置数据库成为了一种常见的实践。本文旨在介绍如何通过Shell脚本…

内网(极空间)搭建gitlab跳板机转发端口及域名配置

背景说明 https://blog.csdn.net/GodDavide/article/details/139182475 上文说到: 我已经用docker搭好了gitlab-ce服务&#xff0c;但我是部署在自己的家庭nas-极空间z4pro里的&#xff0c;属于内网环境。 另外我有一台阿里云服务器&#xff0c;做跳板机。 我有一个阿里的域名…

老Java学 Go 笔录(二) 从 go 的编译开始学起

目录 一.版本选择二.环境准备三.工具的选择四.第一个 hello go4.1 开发4.2 编译4.3 编译运行4.4 直接安装 五.用 go 快速搭建 webserver六.调用外部三方方法七.go vs java 的执行 前言 专栏旨在利用现有的 java 体系内容去完成 go 语言的学习. 本次行文是在 https://go.dev/doc…