C++ ——继承
体现的是代码复用的思想
1、子类继承父类,子类就拥有了父类的特性(成员方法和成员属性)
2、已存在的类被称为“基类”或者“父类”或者“超类”;新创建的类被称为“派生类”或者“子类”
注意:
(1)子类继承了父类,子类就拥有了父类的属性和方法
(2)如果子类重写了父类的同名方法,子类对象默认调用的是子类自己的成员方法,如果想调用父类的同名方法,要添加父类作用域限定符
#include <iostream>using namespace std;class Father{public:int num1=88;int num2=99;public://成员方法void show()const{cout<<"num1="<<num1<<",num2="<<num2<<endl;}void cook(){cout<<"做水煮鱼"<<endl;}};class Son:public Father{ //public:放在继承的地方,表示继承方式是公有继承public:void sing(){cout<<"唱歌"<<endl;}void cook(){cout<<"做红烧肉"<<endl;}};int main(){Son s1;s1.cook(); //默认子类调用的是自己的成员方法s1.show();s1.sing();s1.Father::cook(); //子类可以使用添加父类作用域限定符,来调用父类的同名方法return 0;}
1、构造函数
1.1 派生类的构造函数
继承中的无参构造函数
(1)基类(父类)中的构造函数不能被继承
(2)派生类(子类)中必须要调用基类中的构造函数来完成属性的初始化
(3)默认情况下,编译器会自动在派生类中调用父类的无参构造函数
(4)子类继承了父类,子类独有的属性需要在自己的构造函数进行初始化,而子类从父类继承过来的属性,必须通过子类构造函数调用父类构造函数进行初始化
#include <iostream>using namespace std;class Father{public:int num1=88;int num2=99;public://编译器默认的无参构造函数Father(){}//有参构造函数Father(int num1,int num2):num1(num1),num2(num2){}};class Son:public Father{ //public:放在继承的地方,表示继承方式是公有继承public:int a;public://编译器默认的子类无参调用父类无参构造函数Son():Father(){}//子类有参构造函数调用父类有参构造函数,来完成继承下来的属性的初始化Son(int num1,int num2,int a):Father(num1,num2),a(a){}};int main(){Son s2(10,55,66);// s2.show();cout<<s2.a<<endl; //66return 0;}
1.2 派生类调用基类构造函数
(1)目的:因为构造函数和析构函数,不能继承,所以派生类的构造函数通过调用基类的构造函数完成部分属性的初始化
(2)派生类的构造函数调用基类的构造函数的方式:透传构造、委托构造、继承构造
1.2.1 透传构造
派生类的构造函数直接调用基类的构造函数
class Father{public:int num;public://无参构造函数---->委托构造Father():Father(90){}//有参构造函数Father(int num):num(num){}};class Son:public Father{ //public:放在继承的地方,表示继承方式是公有继承public:int num1;public://委托构造Son():Son(2,88){}//透传构造Son(int num1,int num):Father(num),num1(num1){}};
1.2.2 委托构造
可维护性好,但效率相对较低
思想:一个类中的构造函数是可以调用这个类中的其他构造函数
父类的无参构造函数调用父类的有参构造函数;子类的无参构造函数调用子类的有参构造函数;子类的有参构造函数透传父类的有参构造函数
注意:委托构造离不开透传构造
class Father{public:int num;public://无参构造函数---->委托构造Father():Father(90){}//有参构造函数Father(int num):num(num){}};class Son:public Father{ //public:放在继承的地方,表示继承方式是公有继承public:int num1;public://委托构造Son():Son(2,88){}//透传构造Son(int num1,int num):Father(num),num1(num1){}};
1.2.3 继承构造
透传构造的简写方式,一句话自动实现透传构造,编译器会自动给派生类添加n个构造函数(n取决于基类中构造函数的个数),并实现自动透传其基类构造函数
class Father{public:int num;int age;string addr;public://无参构造函数---->委托构造Father():Father(90){}//有参构造函数Father(int num):num(num){}Father(int age,string addr):age(age),addr(addr){}};class Son:public Father{ //public:放在继承的地方,表示继承方式是公有继承public:int num1=99;public://继承构造using Father::Father;};
2、对象的构建和销毁的过程
(1)成员对象:类中有一个成员,该成员是对象类型,叫做对象成员
先调用成员对象的构造函数,再调用自己的构造函数;析构函数则相反
(2)父子类继承时
先调用父类的构造函数,再调用子类的构造函数;析构函数则相反
(3)静态成员对象:类中有一个静态成员,该成员是一个对象类型
静态成员对象的构造函数先执行,再执行自己的构造函数;析构函数则相反
顺序:
构造函数:静态成员对象---->成员对象---->父类---->子类
析构函数:子类---->父类---->成员对象---->静态成员对象
2.1 成员对象
class Demon{public://构造函数Demon(){cout<<"成员对象的构造函数"<<endl;}~Demon(){cout<<"成员对象的析构函数"<<endl;}};class Test{public:Test(){cout<<"构造函数"<<endl;}~Test(){cout<<"析构函数"<<endl;}};
2.2 父子类继承时
class Father{public:Father(){cout<<"父类构造"<<endl;}~Father(){cout<<"父类析构"<<endl;}};class Son:public Father{public:Son():Father(){cout<<"子类构造"<<endl;}~Son(){cout<<"子类析构"<<endl;}};
2.3 静态成员对象
class P{public:P(){cout<<"静态成员对象的构造"<<endl;}~P(){cout<<"静态成员对象的析构"<<endl;}};class Phone{public://类内声明static P p1; //静态成员变量的声明Phone(){cout<<"构造函数"<<endl;}~Phone(){cout<<"析构函数"<<endl;}};P Phone::p1=P(); //类外初始化
3、权限
3.1 权限修饰符
C++中成员的权限修饰符有3种:
(1)public:共有的 类内、子类内、类外可以访问
(2)private:私有的 只能类内访问
(3)protected:受保护的 类内、子类内可以访问
注意:如果权限修饰符可以省略,默认是private
#include <iostream>using namespace std;class Father{public:int num1;private:int num2;protected:int num3;public://构造函数Father(int num1,int num2,int num3):num1(num1),num2(num2),num3(num3){}void show()const{cout<<this->num1<<" "; //public 类内可以访问cout<<this->num2<<" "; //private 类内可以访问cout<<this->num3<<" "; //protected 类内可以访问cout<<"*******"<<endl;}};class Son:public Father{public:using Father::Father;void fun()const{cout<<this->num1<<" "<<this->Father::num1<<" "; //public 子类内可以访问cout<<this->num3<<" "<<this->Father::num3<<" "; //protected 子类内可以访问cout<<"*******"<<endl;}};int main(){Father f1(1,2,3);f1.show();Son s1(4,5,6);s1.fun();cout<<s1.num1<<endl; //public 类外可以访问return 0;}
3.2 继承方式
3.2.1 public(共有继承)
(1)父类是public---->子类也是public
(2)父类是protected---->子类也是protected
(3)父类是private---->子类也是private,但是类内不可以直接访问,可以间接访问
#include <iostream>using namespace std;class Father{public:int num1;protected:int num2;private:int num3;public:Father(int num1,int num2,int num3):num1(num1),num2(num2),num3(num3){}void fun()const{}int get_num3()const{return num3;}};class Son:public Father{public:Son(int num1,int num2,int num3):Father(num1,num2,num3){}void show(){cout<<this->num1<<endl; //父类public---->子类也是public,类内可以访问cout<<this->num2<<endl; //父类protected---->子类也是protected// cout<<this->num3<<endl; //报错,父类private---->子类也是private,但是类内不可以直接访问cout<<this->Father::get_num3()<<endl; //父类private---->子类也是private,可以间接访问cout<<"******"<<endl;}};class Sunzi:public Son{public:Sunzi(int num1,int num2,int num3):Son(num1,num2,num3){}void fun()const{cout<<this->num1<<" "<<this->Son::num1<<endl; //父类public---->子类也是public,派生类内可以访问cout<<this->num2<<" "<<this->Son::num2<<endl; //父类protected---->子类也是protectedcout<<"******"<<endl;}};int main(){Son s1(1,2,3);s1.show();cout<<s1.num1<<endl; //父类public---->子类也是public,类外可以访问Sunzi sz(4,5,6);sz.fun();return 0;}
3.2.2 protected(受保护的继承)
(1)父类是public---->子类是protected
(2)父类是protected---->子类也是protected
(3)父类是private---->子类也是private,但是类内不可以直接访问,可以间接访问
#include <iostream>using namespace std;class Father{public:int num1;protected:int num2;private:int num3;public:Father(int num1,int num2,int num3):num1(num1),num2(num2),num3(num3){}void fun()const{}int get_num3()const{return num3;}};class Son:protected Father{public:Son(int num1,int num2,int num3):Father(num1,num2,num3){}void show(){cout<<this->num1<<endl; //父类public---->子类是protectedcout<<this->num2<<endl; //父类protected---->子类也是protected// cout<<this->num3<<endl; //报错,父类private---->子类也是private,但是类内不可以直接访问cout<<this->Father::get_num3()<<endl; //父类private---->子类也是private,可以间接访问cout<<"******"<<endl;}};class Sunzi:protected Son{public:Sunzi(int num1,int num2,int num3):Son(num1,num2,num3){}void fun()const{cout<<this->num1<<" "<<this->Son::num1<<endl; //父类public---->子类是protectedcout<<this->num2<<" "<<this->Son::num2<<endl; //父类protected---->子类也是protectedcout<<"******"<<endl;}};int main(){Son s1(1,2,3);s1.show();Sunzi sz(4,5,6);sz.fun();return 0;}
3.2.3 private(私有继承)
(1)父类是public---->子类是private,类内可以直接访问
(2)父类是protected---->子类是private,类内可以直接访问
(3)父类是private---->子类也是private,但是类内不可以直接访问,可以间接访问
4、多重继承
4.1 概念
继承中,允许有多个基类,每一个基类的继承都可以看作是唯一的独一继承,此时派生类就拥有了所有基类的特性
#include <iostream>using namespace std;class Sofa{public:int num=1;public:void job(){cout<<"沙发可以坐"<<endl;}};class Bed{public:void work(){cout<<"床可以躺"<<endl;}};class SofsBed:public Sofa,public Bed{public:void work(){cout<<"即可以躺又可以坐"<<endl;}};int main(){SofsBed sfb;sfb.job();sfb.work();cout<<sfb.num<<endl;sfb.Bed::work();return 0;}
问题:多个基类同时拥有同名成员函数,此时派生类对象直接调用该函数会产生歧义
解决方法:添加基类作用域限定符
4.2 菱形继承
多继承中的若干个基类,又同时拥有同一个基类,此时叫菱形继承(钻石继承)
#include <iostream>using namespace std;//爷爷类class Furniture{public:void show(){cout<<"我们是家具"<<endl;}};//基类class Sofa:virtual public Furniture{};class Bed:virtual public Furniture{};//派生类class SofsBed:public Sofa,public Bed{};int main(){SofsBed sfb;// sfb.show(); //报错,问题:两个基类拥有了同名函数,产生了歧义//解决方法1:使用基类作用域限定符sfb.Bed::show();sfb.Sofa::show();//解决方法2:使用虚继承/*继承方式有两种:普通继承(默认的)和虚继承(继承方式前添加virtual关键字)*/sfb.show();return 0;}
相关文章:
C++ ——继承
体现的是代码复用的思想 1、子类继承父类,子类就拥有了父类的特性(成员方法和成员属性) 2、已存在的类被称为“基类”或者“父类”或者“超类”;新创建的类被称为“派生类”或者“子类” 注意: (1&#…...
LeetCode 热题 100 283. 移动零
LeetCode 热题 100 | 283. 移动零 大家好,今天我们来解决一道经典的算法题——移动零。这道题在LeetCode上被标记为简单难度,要求我们将数组中的所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。下面我将详细讲解解题思路,…...
游戏引擎学习第116天
回顾昨天的工作 本次工作内容主要集中在游戏开发的低级编程优化,尤其是手动优化软件渲染。工作目的之一是鼓励开发者避免依赖外部库,而是深入理解代码并进行优化。当前阶段正进行SIMD(单指令多数据)优化,使用Intel推荐…...
react(9)-redux
使用CRA快速创建react项目 npx create-react-app react-redux 安装配套工具 npm i reduxjs/toolkit react-redux 启动项目 在创建项目时候会出现一个问题 You are running create-react-app 5.0.0, which is behind the latest release (5.0.1). We no longer support…...
Linux内核实时机制7 - 实时改造机理 - 软中断优化下
Linux内核实时机制7 - 实时改造机理 - 软中断优化下 https://blog.csdn.net/u010971180/article/details/145722641以下分别以Linux4.19、Linux5.4、Linux5.10、Linux5.15 展开分析,深入社区实时改造机理的软中断优化过程。https://blog.csdn.net/weixin_41028621/article/det…...
企业知识管理平台重构数字时代知识体系与智能服务网络
内容概要 现代企业知识管理平台的演进呈现出全生命周期管理与智能服务网络构建的双重特征。通过四库体系(知识采集库、加工库、应用库、评估库)的协同运作,该系统实现了从知识沉淀、结构化处理到价值释放的完整闭环。其中,知识图…...
大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(3)
Paimon的下载及安装,并且了解了主键表的引擎以及changelog-producer的含义参考: 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(1) 利用Paimon表做lookup join,集成mysql cdc等参考: 大数据组件(四)快速入门实时数据…...
SVN把英文换中文
原文链接:SVN设置成中文版本 都是英文,换中文 Tortoise SVN 安装汉化教程(乌龟SVN) https://pan.quark.cn/s/cb6f2eee3f90 下载中文包...
Ubuntu 的RabbitMQ安装
目录 1.安装Erlang 查看erlang版本 退出命令 2. 安装 RabbitMQ 3.确认安装结果 4.安装RabbitMQ管理界面 5.启动服务并访问 1.启动服务 2.查看服务状态 3.通过IP:port 访问界面 4.添加管理员用户 a)添加用户名:admin,密码࿱…...
基于WebRTC与AI大模型接入EasyRTC:打造轻量级、高实时、强互动的嵌入式音视频解决方案
随着物联网和嵌入式技术的快速发展,嵌入式设备对实时音视频通信的需求日益增长。然而,传统的音视频解决方案往往存在体积庞大、实时性差、互动体验不佳等问题,难以满足嵌入式设备的资源限制和应用场景需求。 针对以上痛点,本文将介…...
QML 实现一个动态的启动界面
QML 实现一个动态的启动界面 一、效果查看二、源码分享三、所用到的资源下载 一、效果查看 二、源码分享 工程结构 main.qml import QtQuick import QtQuick.Controls import QtQuick.Dialogs import Qt.labs.platformWindow {id:windowwidth: 640height: 400visible: truetit…...
智能预警系统标准化处理流程
在当今数字化时代,IT系统的稳定运行对企业的业务连续性至关重要。为了及时发现和响应系统异常,构建智能预警系统已成为许多企业的当务之急。但仅仅拥有预警系统还不够,我们还需要一套标准化的处理流程,确保问题能够高效、有序地得到解决。 © ivwdcwso (ID: u012172506) 一…...
Unity游戏制作中的C#基础(4)数组声明和使用
一、数组的声明 在 C# 中,声明数组有多种方式,每种方式都有其适用的场景,下面为你逐一详细介绍: 1. 直接初始化声明 这种方式直观且便捷,在声明数组的同时就为其赋初值,让数组从诞生之初就拥有了具体的数据…...
tailwindcss学习03
01 入门 02 vue中接入 03 工具类优先 准备 vue.svg <svg viewBox"0 0 40 40" xmlns"http://www.w3.org/2000/svg"> <defs> <linearGradient x1"50%" y1"0%" x2"50%" y2"100%" id"a"&…...
QML Component 与 Loader 结合动态加载组件
在实际项目中,有时候我们写好一个组件,但不是立即加载出来,而是触发某些条件后才动态的加载显示出来,当处理完某些操作后,再次将其关闭掉; 这样的需求,可以使用 Component 包裹着组件ÿ…...
Visual studio 2022 将打开文件的方式由单击改为双击
1. 打开vs2022,选择Tools -> Options打开Options设置页面 2. 在左侧依次展开Environment, 选择Tabs and Windows 3. 在右侧面板往下拖拽滚动条,找到Preview Tab section, unchecked "Preview selected files in Solution Explorer (Altclick t…...
网络工程师 (49)UDP协议
前言 UDP协议,即用户数据报协议(User Datagram Protocol),是一种无连接的、不可靠的、面向报文的传输层通信协议。 一、基本特点 无连接性:UDP在发送数据之前不需要与目标设备建立连接,也无需在数据发送结束…...
了解大数据
一、大数据的特点: 1.大量 2.高速 3.多样 结构化数据和非结构化数据 4.低价值密度 二、大数据的应用场景:视频推荐、电商推荐等 三、大数据的技术发展脉络 阶段1:单机时代 阶段2:大数据时代-分布式处理 阶段3:实…...
命令模式
1. 命令模式简介 命令模式(Command Pattern)是一种行为型设计模式,它将一个请求封装为一个对象,从而使您可以用不同的请求对客户进行参数化、对请求排队或记录请求日志,以及支持可撤销的操作。命令模式的核心思想是将操作和操作的执行者解耦,使得操作可以独立于执行者进…...
解放大脑!用DeepSeek自动生成PPT!
DeepSeek应用(PPT篇) DeepSeek作为当前最好的AI大模型之一,其强大的文本生成能力被广泛的应用于各个领域,本文我们来聊聊用DeepSeek来自动生成PPT。 一、DeepSeek & PPT DeepSeek本身没有直接生成PPT的能力,换个…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
WinUI3开发_使用mica效果
简介 Mica(云母)是Windows10/11上的一种现代化效果,是Windows10/11上所使用的Fluent Design(设计语言)里的一个效果,Windows10/11上所使用的Fluent Design皆旨在于打造一个人类、通用和真正感觉与 Windows 一样的设计。 WinUI3就是Windows10/11上的一个…...
关于 ffmpeg设置摄像头报错“Could not set video options” 的解决方法
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/148515355 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...
