6.C++:继承

一、继承

//1.类中的保护和私有在当前类中没有差别;

//2.在继承后的子类中有差别,private在子类中不可见,所以用protected;

class person
{
public:void print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}
protected:     //若换为private,则执行错误string _name = "peter";int _age = 18;
};class student: public person
{
protected:int stuid;
};
int main()
{student s;s.print();return 0;
}

二、 基类和派生类对象赋值转换

class person
{
protected:string _name;string _sex;int _age;
};
class student: public person
{
protected:int stuid;
};
int main()
{person p;student s;//子类和父类之间的赋值兼容规则//1.子类对象可以赋值给父类对象/指针/引用p = s;person* ptr = &s;person& ref = s;//反过来s = p;     //不可以student* ptr = &p; //有时候可以student& ref = p;return 0;
}

指针ptr指向student类中父类的那一部分;

引用ref是子类student中父类那一部分的别名; 


三、继承中的作用域

class person
{
protected:string _name = "peter";int _num = 111;
};
class student: public person
{
public:void print(){cout << "姓名:" << _name << endl;cout << "学号:" << _num << endl;}
protected:int _num = 999;
};
int main()
{student s;s.print();   return 0;
}
//输出: 姓名:peter// 学号:999

//1.两个_num在不同的作用域中,一个在父类,一个在子类,不会报错;

//2.当父类和子类同时有同名成员时,子类的成员隐藏于父类的成员(重定义);

//优先访问子类,现在子类中找,再去父类;

 访问父类_num:

class person
{
protected:string _name = "peter";int _num = 111;
};
class student: public person
{
public:void print(){cout << "姓名:" << _name << endl;cout << "学号:" << _num << endl;cout << "学号:" << person::_num << endl; //指定作用域即可}
protected:int _num = 999;
};
int main()
{student s;s.print();return 0;
}

 //1.A和B的fun构成什么关系?

//重定义(隐藏),不是重载,重载必须在同一个作用域

//函数只要函数名相同,不需要参数相同

class A
{
public:void fun(){cout << "func()" << endl;}
};
class B : public A
{
public:void fun(int i){A::fun();cout << "func(int i)->" << i << endl;}
};int main()
{B b;b.fun(); //执行错误b.fun(123456);b.A::fun(); //调用A的fun()return 0;
}

四、派生类的默认成员函数

class Person
{
public://1.构造函数Person(const char* name = "peter"): _name(name){cout << "Person()" << endl;}//2.拷贝构造Person(const Person& p): _name(p._name){cout << "Person(const Person& p)" << endl;}//3.赋值Person& operator=(const Person& p){cout << "Person operator=(const Person& p)" << endl;if (this != &p)_name = p._name;return *this;}//4.析构函数~Person(){cout << "~Person()" << endl;}
protected:string _name;
};class Student : public Person
{
public:Student(const char* name, int num): Person(name) //调用父类的构造函数, _num(num){cout << "Student()" << endl;}Student(const Student& s): Person(s) //调用父类的拷贝构造, _num(s._num){cout << "Student(const Student& s)" << endl;}Student& operator=(const Student& s){if (this != &s){Person::operator =(s);//重定义,调用父类的person::_num = s._num;}cout << "Student& operator= (const Student& s)" << endl;return *this;}~Student()  {// Person::~Person();//与~Person()构成隐藏cout << "~Student()" << endl;//调用子类析构后会自动调用父类析构}
protected:int _num; //学号
};
int main()
{Student s1("peter",11);Student s2(s1);return 0;
}

//输出:

Person()   //父类构造
Student()  //子类构造
Person(const Person& p)  //父类拷贝构造
Student(const Student& s)  //子类拷贝构造
~Student()   //s2析构
~Person()    //子类调用析构,自动调用父类析构
~Student()  //s1析构
~Person()

int main()
{Student s1("peter",11);Student s3("rose",20);s1 = s3;return 0;
}

 //输出:

Person()  //s1构造
Student()
Person()  //s2构造
Student()
Person operator=(const Person& p)  //父类赋值
Student& operator= (const Student& s)  //子类赋值
~Student()  //s3析构
~Person()
~Student()  //s1析构
~Person()


如何设计一个不能被继承的类? 

构造函数私有化,不能被继承,对象无法生成

class A
{
private:A(){}
};
class B :public A
{};

五、友元与继承

友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员
class Student; //注意
class Person
{
public:friend void Display(const Person& p, const Student& s);
protected:string _name;
};
class Student : public Person
{friend void Display(const Person& p, const Student& s);
protected:int _stuNum; 
};void Display(const Person& p, const Student& s)
{cout << p._name << endl;cout << s._stuNum << endl;
}
int main()
{Person p;Student s;Display(p, s);return 0;
}

 或者:

class Student;
class Person
{
protected:string _name;
};
class Student : public Person
{friend void Display(const Person& p, const Student& s);
protected:int _stuNum; 
};void Display(const Person& p, const Student& s)
{cout << s._name << endl;cout << s._stuNum << endl;
}
int main()
{Person p;Student s;Display(p, s);return 0;
}

六、继承与静态成员

基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例 。
class Person
{
public:Person() { ++_count; }string _name; static int _count; 
};
int Person::_count = 0;
class Student : public Person
{
public:int _stuNum; 
};
int main()
{Person p;Student s;p._name = "jack";s._name = "rose";p._count = 1;s._count = 2;cout << Person::_count << endl;return 0;
}

_count放在静态区,只有一个_count,p和s中的_count是一个


七、复杂的菱形继承及菱形虚拟继承

单继承:一个子类只有一个直接父类时称这个继承关系为单继承
多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承
菱形继承:菱形继承是多继承的一种特殊情况

菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。在Assistant的对象中Person成员会有两份。

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";// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}

解决方法:

class Person
{
public:string _name; // 姓名
};
class Student : virtual public Person
{
protected:int _num; //学号
};
class Teacher : virtual public Person
{
protected:int _id; // 职工编号
};

virual分析:

 


八、继承和组合

//1.public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。
//2.组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象。
//3.继承与组合都可以的情况下,优先使用对象组合,而不是类继承 。
// Car和BMW Car和Benz构成is-a的关系
class Car {
protected:string _colour = "白色"; // 颜色string _num = "陕ABIT00"; // 车牌号
};class BMW : public Car {
public:void Drive() { cout << "好开-操控" << endl; }
};class Benz : public Car {
public:void Drive() { cout << "好坐-舒适" << endl; }
};
// Tire和Car构成has-a的关系
class Tire {
protected:string _brand = "Michelin"; // 品牌size_t _size = 17; // 尺寸
};
class Car {
protected:string _colour = "白色"; // 颜色string _num = "陕ABIT00"; // 车牌号Tire _t; // 轮胎
};

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

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

相关文章

【Qt 学习笔记】Qt常用控件 | 按钮类控件Push Button的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 按钮类控件Push Button的使用及说明 文章编号&#xff1…

2024年华中杯数学建模竞赛全攻略:ABC题思路解析+代码实现+数据集+论文撰写+全程答疑

引言 &#xff08;比赛后所有题目资料在文末获取呀&#xff09; 华中杯数学建模竞赛是数学建模领域的一项重要赛事&#xff0c;它不仅考验参赛者的数学建模能力&#xff0c;还考验了编程技能、数据分析能力和论文撰写能力。为了帮助参赛者更好地准备2024年的竞赛&#xff0c;本…

RAG学习笔记系列(一)

RAG 介绍 RAG 全称为 Retrieval Augmented Generation&#xff08;检索增强生成&#xff09;。是基于LLM构建系统的一种架构。 RAG 基本上可以理解为&#xff1a;搜索 LLM prompting。根据用户的查询语句&#xff0c;系统会先使用搜索算法获取到相关内容作为上下文&#xff0…

pnpm 报错: ERR_PNPM_META_FETCH_FAIL

今天突然遇到一个报错&#xff0c;pnpm 报错&#xff1a; ERR_PNPM_META_FETCH_FAIL  GET https://registry.npm.taobao.org/vue%2Fcli-service: request to https://registry.npm.taobao.org/vue%2Fcli-service failed, reason: certificate has expired问题原因&#xff1a;…

when语法学习及判断主机别名实例

目录 1、概念 2、实例配置 2.1 编写剧本体验when的用法 2.2 执行剧本文件 2.3 使用ansible临时命令进行测试 1、概念 when是用于判断的语法&#xff0c;将其用在每个动作的下方进行判断&#xff0c;使得只有在满足条件才会执行。 2、实例配置-判断主机别名 在每个客户端中…

Compose 基础组件

文章目录 Compose 基础组件Modifier 修饰符Scaffold 脚手架 Compose 基础组件 Modifier 修饰符 在传统视图体系中&#xff0c;使用XML文件描述组件的样式&#xff0c;而在Compose中使用Modifier&#xff0c;每个基础的Composable组件都有一个modifier参数&#xff0c;通过Mod…

使用CCS软件查看PID曲线

在刚开始学习PID的时候&#xff0c;都需要借助PID的曲线来理解比例&#xff0c;积分&#xff0c;微分这三个参数的具体作用。但是这些曲线生成一般都需要借助上位机软件或者在网页上才能实现。如果是在单片机上调试程序的话&#xff0c;想要看曲线&#xff0c;一般就是通过串口…

【YOLOv5】使用yolov5训练模型时报错合集

文章目录 前言问题1 -- VsCode终端无法进入Anaconda创建的虚拟环境【问题描述】【问题分析】【解决方式】方法一方法二 问题2 -- 怎么在VsCode中为项目配置Anaconda创建的虚拟环境【问题描述】【解决方式】 问题3 -- yolov5训练模型时报错RuntimeError: result type Float cant…

web自动化测试系列-selenium常用方法定位(五)

目录 1.selenium的定位方法 2.操作案例 3.实现代码 前面我们介绍了html页面元素主要是通过标签和属性来进行定位 &#xff0c;只要满足唯一&#xff0c;无论是标签还是属性 &#xff0c;都能进行定位 。当然 &#xff0c;我们要通过selenium来进行定位 &#xff0c;同样还是…

基于SpringBoot的在线五子连珠的设计与实现,前端采用vue框架;后端采用SpringBoot,mybatis

介绍 基于SpringBoot的在线五子连珠的设计与实现&#xff0c;主要是设计一款五子棋游戏&#xff0c;涉及登录注册的功能&#xff0c;人机对战、联机对战和积分排行榜的功能。其中人机对战中&#xff0c;电脑采用的是采用了一种基于局面分析的评分算法来确定机器人的下一步落子…

线程池学习(通俗易懂)

线程池 线程池是什么ThreadPoolExecutor模拟实现线程池结语 线程池是什么 假设我们要频繁的创建线程和销毁线程,但是创建线程和销毁线程是有成本的. 所以我们可以提前创建一批线程,后面需要使用的时候,直接拿就可以了,这就是线程池. 当线程不再使用的时候,就归还到池子里.为什…

图片懒加载

看下tuniu的页面&#xff0c;这有两个属性src和data-src <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><t…

SpringBoot3 + Kotlin + mybatis-plus + Swagger3后端开发样例

前言&#xff1a; Kotlin 是一种在 JVM&#xff08;Java 虚拟机&#xff09;、Android 和浏览器端运行的静态类型编程语言。以下是关于 Kotlin 的总结介绍&#xff1a; 1、语言特性&#xff1a; 简洁性&#xff1a;Kotlin 旨在提供简洁且安全的代码&#xff0c;同时保持与 Jav…

什么是反向 ETL?为什么它很有价值?

提取、转换、加载 &#xff08;ETL&#xff09; 过程已经成熟并被广泛采用。 它只涉及从各种源系统中获取数据&#xff0c;将其转换为标准化数据模型&#xff0c;然后将其加载到数据仓库中。从那里&#xff0c;您的团队使用其商业智能 &#xff08;BI&#xff09; 和分析工具中…

云轴科技ZStack入选中国信通院《高质量数字化转型产品及服务全景图(2023年度)》

近日&#xff0c;由中国互联网协会主办、中国信通院承办的“2024高质量数字化转型创新发展大会”暨“铸基计划”年度会议在北京成功召开。 本次大会发布了2024年度行业数字化转型趋势&#xff0c;总结并展望了“铸基计划”2023年取得的工作成果及2024年的工作规划。同时&#…

谷粒商城实战(013 业务-认证服务-短信验证)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第211p-第p219的内容 介绍 认证中心要集成 社交登录、OAuth2.0、单点登录 等功能 OAuth 2.0&#xff1a; 问题解决&#xff1a; OAuth 2.0 主要…

10分钟1000台虚机 云安全效能双升 亚信安全新信舱无代理云平台快速适配版正式发布

新信舱 亚信安全新信舱无代理云平台快速适配版正式发布。在云平台依赖性、无代理部署速度、宿主机无代理AV防护和虚拟机缓存扫描性能等方面&#xff0c;新信舱无代理版本提供了无缝的可扩展性、低资源消耗并降低管理复杂性&#xff0c;让安全防护真正做到了 多快好省&#xff…

Linux基本指令(1)

目录 ls指令&#xff1a; pwd命令&#xff1a; cd指令&#xff1a; touch指令&#xff1a; mkdir指令&#xff1a; rmdir指令&&rm指令&#xff1a; man指令&#xff1a; cp指令&#xff1a; ls指令&#xff1a; 语法&#xff1a;ls [选项][目录或者文件] 作用…

突破传统WAF的瓶颈·WAAP平台将是未来发展的必然趋势

近年来&#xff0c;基础组件相继爆出严重的高危漏洞&#xff0c;层出不穷的“核弹级”0-day漏洞事件不断破圈&#xff0c;Web应用已成攻击者首要目标&#xff0c;让整个泛IT行业都难堪其扰&#xff0c;疲于应对。根据Gartner调查显示&#xff0c;信息安全攻击有75%都是发生在We…

【C++庖丁解牛】C++11---统一的列表初始化 | auto | decltype | nullptr | STL中一些变化

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 1. C11简介2. 统一的列表…