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

C++ Day6

目录

一、菱形继承

1.1 概念

1.2 格式

二、虚继承

2.1 作用

2.2 格式

2.3注意

三、多态

3.1函数重写

3.2 虚函数

3.3 赋值兼容规则

3.4 多态中,函数重写的原理

3.5 虚析构函数

3.5.1 格式

3.6 纯虚函数

3.6.1格式

四、抽象类

五、模板

5.1模板的特点

5.2 函数模板

5.2.1作用

5.2.2 格式

 六、练习

1.定义一个基类 Animal,其中有一个虚函数 perform(),用于在子类中实现不同的表演行为。

 结果为:

2.用函数模板实现不同数据类型的交换功能。

结果为:


一、菱形继承

1.1 概念

菱形继承又称为钻石继承,由公共基类派生出多个中间子类,又由多个中间子类共同派生出汇聚子类。汇聚子类会得到,中间子类从公共基类继承下来的多份成员。

问题:

汇聚子类会得到,中间子类从公共基类继承下来的多份成员,造成空间浪费,没有必要,还会对公共基类的成员多次初始化,或释放。

1.2 格式

                 A       --------公共基类/    \B      C    ------- 中间子类\    /D       --------汇聚子类

 解决:虚继承

#include <iostream>using namespace std;//封装公共基类 家具 类
class Jiaju
{
private:string color;
public://无参构造Jiaju() {cout << "家具的无参构造函数" << endl;}//有参构造Jiaju(string n):color(n){cout << "家具的有参构造函数" << endl;}
};//中间子类
//封装 沙发的类
class Sofa:public Jiaju
{
private:string sitting;
public://无参构造Sofa() {cout << "沙发的无参构造" << endl;}//有参构造函数Sofa(string s,string c):Jiaju(c),sitting(s){cout << "沙发的有参构造" << endl;}void display(){cout << sitting << endl;}
};//中间子类
//封装 床 类
class Bed:public Jiaju
{
private:string sleep;public://无参Bed() {cout << "床的无参构造" << endl;}//有参Bed(string s,string c):Jiaju(c),sleep(s){cout << "床的有参构造" << endl;}void display(){cout << sleep << endl;}
};//汇聚子类
//封装 沙发床类  继承于沙发 和 床
class Sofa_Bed:public Bed,public Sofa
{
private:int w;
public://Sofa_Bed(){cout << "沙发床的无参构造" << endl;}//有参构造Sofa_Bed(string sit, string s, int w,string c):Bed(s,c),Sofa(sit,c),w(w){cout << "沙发床的有参构造" << endl;}
};int main()
{
//    Sofa_Bed s;Sofa_Bed s1("可坐","可躺",123,"pink");return 0;
}

二、虚继承

2.1 作用

可以让汇聚子类只保留一份 中间子类从公共基类继承下来的成员。

2.2 格式

在中间子类的继承方式前 加上 virtual

class 类名 : virtual 继承方式 类名   //中间子类
{中间子类的拓展;
};

2.3注意

1> 中间子类虚继承公共基类后,汇聚子类的初始化列表,先调用中间子类的有参构造函数,中间子类再调用公共基类的有参构造函数,但是呢,虚继承之后,只保留一份中间子类从公共基类继承下来的有参构造函数,意味着不知道调用哪一个中间子类继承下来的公共基类的构造函数,这样就会默认调用公共基类的无参构造函数。

2> 如果汇聚子类想要对公共基类的数据成员初始化,需要显性调用公共基类的构造函数。

#include <iostream>using namespace std;//封装公共基类 家具 类
class Jiaju
{
private:string color;
public://无参构造Jiaju() {cout << "家具的无参构造函数" << endl;}//有参构造Jiaju(string n):color(n){cout << "家具的有参构造函数" << endl;}
};//中间子类
//封装 沙发的类
class Sofa:virtual public Jiaju  //中间子类虚继承公共基类
{
private:string sitting;
public://无参构造Sofa() {cout << "沙发的无参构造" << endl;}//有参构造函数Sofa(string s,string c):Jiaju(c),sitting(s){cout << "沙发的有参构造" << endl;}void display(){cout << sitting << endl;}
};//中间子类
//封装 床 类
class Bed:virtual public Jiaju  //中间子类虚继承公共基类
{
private:string sleep;public://无参Bed() {cout << "床的无参构造" << endl;}//有参Bed(string s,string c):Jiaju(c),sleep(s){cout << "床的有参构造" << endl;}void display(){cout << sleep << endl;}
};//汇聚子类
//封装 沙发床类  继承于沙发 和 床
class Sofa_Bed:public Bed,public Sofa
{
private:int w;
public://Sofa_Bed(){cout << "沙发床的无参构造" << endl;}//有参构造Sofa_Bed(string sit, string s, int w,string c):Jiaju(c),Bed(s,c),Sofa(sit,c),w(w) //需要在汇聚子类中显性调用公共基类的有参构造函数{cout << "沙发床的有参构造" << endl;}
};int main()
{
//    Sofa_Bed s;Sofa_Bed s1("可坐","可躺",123,"pink");return 0;
}

三、多态

类的三大属性:封装、继承、多态

静态多态(函数重载)、动态多态(运行时)

一种形式多种状态

多态就像一个人,可以有很多角色或者行为,取决于不同情境

父类的指针或者引用,指向或初始化子类的对象,调用子类对父类重写的函数,进而展开子类的功能。

3.1函数重写

1> 必须有继承关系

2> 子类和父类有同名同类型的函数

3> 父类中的该函数必须是虚函数

3.2 虚函数

1> 在函数前加上 virtual ---->该函数是虚函数

2> 虚函数满足继承,也就是说父类中该函数是虚函数,继承到子类中,该函数依旧是虚函数,如果子类再被继承,“孙类”中该函数还是虚函数....

#include <iostream>using namespace std;// 封装 周 这个类
class Zhou
{
private:string name;int age;
public://无参构造Zhou() {}//有参构造函数Zhou(string n, int a):name(n),age(a){}//virtual void speek()  //表示该函数是虚函数{cout << "阿巴阿巴。。" << endl;}
};//封装 周老师  类,继承于周类
class Teacher:public Zhou
{
private:int id;public://无参构造Teacher() {}//有参构造Teacher(string n, int a, int d):Zhou(n,a),id(d){}//void speek(){cout << "看我,上多态,认真听讲" << endl;}
};//封装 游戏玩家 类 继承于Zhou类
class Player:public Zhou
{
private:string game;
public://。。Player() {}//有参构造Player(string name, int age, string g):Zhou(name,age),game(g){}//void speek(){cout << "稳住,我们能赢" << endl;}
};int main()
{Teacher t("zhangsan",34,1001);Zhou *p; //父类的指针p = &t;  //父类的指针,指向子类对象  相当于承当老师这个角色p->speek();   // 上课Player g("lisi",45,"王者");p = &g; //此时是游戏玩家这个角色p->speek();return 0;
}

3.3 赋值兼容规则

父类的指针或者引用,指向或初始化子类的对象

3.4 多态中,函数重写的原理

  • 类中有虚函数时,类里就会有一个虚指针,虚指针也满足继承
  • 虚指针在类的最前面,虚指针指向了一个虚函数表,虚函数表里记录了虚函数,包括子类对父类重写的函数。
  • 虚指针和虚函数表是实现多态的重要机制。

3.5 虚析构函数

虚析构函数用来解决 父类指针指向子类时,父类指针释放,导致子类自拓展的空间没有得到释放

3.5.1 格式

virtual 析构函数
{}
#include <iostream>using namespace std;//封装 人 类
class Person
{
private:string name;
public://Person() {}//有参构造函数Person(string n):name(n){}virtual ~Person()  //虚析构函数  满足继承{cout << "Person::析构函数"  << endl;}
};//封装 学生  继承于人
class Stu:public Person
{
private:int id;
public://Stu(){}//有参构造Stu(string n , int i):Person(n),id(i){}~Stu(){cout << "Stu::析构函数" << endl;}
};int main()
{Person *p = new Stu("张三",1001);delete p;   //如果没有虚析构函数,进行释放p是,子类自己拓展的空间就没有释放--内存泄漏return 0;
}

3.6 纯虚函数

当父类中虚函数被子类用来重写,且没有定义的意义,这个时候,一般把父类中的虚函数设置成纯虚函数。

3.6.1格式

virtual 函数返回值类型 函数名(形参列表) = 0; //纯虚函数

四、抽象类

抽象类一般是用来被继承的,它不能实例化出具体的一个对象,抽象类中至少有一个纯虚函数。

如果子类没有对父类的纯虚函数重写,那么子类也是抽象类,不能实例化一个对象

#include <iostream>using namespace std;//..
class A  //抽象类
{
private:int a;
public:A() {}virtual void show() = 0;  //纯虚函数    
};class B:public A
{
public:B() {}    void show()  //如果子类没有对父类的纯虚函数重写,那么子类也是抽象类,不能实例化一个对象{}
};int main()
{B b;return 0;
}

五、模板

模板就是一个通用的模具。大大提高代码的复用性。

C++还有另一个编程思想 ,泛型编程,主要利用的技术 模板

C++中有两个重要的模板机制:函数模板和类模板

5.1模板的特点

1> 模板不能直接使用,它只是一个框架

2> 模板不是万能的

5.2 函数模板

5.2.1作用

建立一个通用的函数,其返回值类型或者形参类型 不具体制定,用一个虚拟的类型来代替。

5.2.2 格式

template <typename T>
函数的声明或定义

解释:

template ----->表示开始创建模板

typename -->表明后面的符号是数据类型,typename 也可以用class代替

T ----->表示数据类型,可以其他符号代替

#include <iostream>using namespace std;//创建函数模板
template <typename T>
void fun(T &a, T &b)
{T temp;temp = a;a = b;b = temp;
}//void fun(int &a, int &b)
//{
//    int temp;
//    temp = a;
//    a = b;
//    b = temp;//}
//void fun(double &a, double &b)
//{
//    double temp;
//    temp = a;
//    a = b;
//    b = temp;
//}//void fun(char &a, char &b)
//{
//    char temp;
//    temp = a;
//    a = b;
//    b = temp;
//}int main()
{int a = 10, b = 20;fun(a,b);cout << a << "  " << b << endl;double c = 1.3, d = 1.4;fun(c, d);cout << c <<  "  " <<  d << endl;return 0;
}

 六、练习

1.定义一个基类 Animal,其中有一个虚函数 perform(),用于在子类中实现不同的表演行为。

以下是一个简单的比喻,将多态概念与生活中的实际情况相联系:

比喻:动物园的讲解员和动物表演

想象一下你去了一家动物园,看到了许多不同种类的动物,如狮子、、猴子等。现在,动物园里有一位讲解员,他会为每种动物表演做简单的介绍。

在这个场景中,我们可以将动物比作是不同的类,而每种动物表演则是类中的函数。而讲解员则是一个基类,他可以根据每种动物的特点和表演,进行相应的介绍。

#include <iostream>using namespace std;class Animal{
protected:string species;
public:Animal(){}Animal(string sp): species(sp){}virtual void perform(){}
};class lion:public Animal{
public:lion(){}lion(string species):Animal(species){}void perform(){cout << Animal::species << "跳火圈" << endl;}
};class elephant:public Animal{
public:elephant(){}elephant(string sp):Animal(sp){}void perform(){cout << Animal::species << "踩背" << endl;}
};class monkey:public Animal{
public:monkey(){}monkey(string sp):Animal(sp){}void perform(){cout << Animal::species << "偷桃" << endl;}
};int main()
{lion it1("辛巴");Animal *p;p = &it1;p->perform();elephant it2("非洲象");p = &it2;p->perform();monkey it3("峨眉山猴子");p = &it3;p->perform();return 0;
}

 结果为:

2.用函数模板实现不同数据类型的交换功能。

#include <iostream>using namespace std;
template <typename T>void fun(T *a, T *b)
{T temp;temp = *a;*a = *b;*b = temp;
}int main()
{int a = 10;int b = 50;char c = 'C';char d = 'D';fun(&a,&b);fun(&c,&d);cout << "a = " << a << " b = " << b << endl;cout << "c = " << c << " d = " << d << endl;return 0;
}

结果为:

相关文章:

C++ Day6

目录 一、菱形继承 1.1 概念 1.2 格式 二、虚继承 2.1 作用 2.2 格式 2.3注意 三、多态 3.1函数重写 3.2 虚函数 3.3 赋值兼容规则 3.4 多态中&#xff0c;函数重写的原理 3.5 虚析构函数 3.5.1 格式 3.6 纯虚函数 3.6.1格式 四、抽象类 五、模板 5.1模板的特…...

分布式系统与微服务的区别是什么?

分布式系统和微服务是两个相关但不同的概念&#xff0c;它们都是在构建复杂的软件应用时使用的架构思想。 分布式系统&#xff1a; 分布式系统是指由多个独立的计算机或服务器通过网络连接共同工作&#xff0c;协同完成一个任务或提供一个服务。在分布式系统中&#xff0c;各个…...

python:用python构建一个物联网平台

要使用Python构建物联网平台&#xff0c;您需要考虑以下步骤&#xff1a; 确定平台的基本要求和功能 首先&#xff0c;您需要明确您将要构建的平台的功能和特点。例如&#xff0c;您可能需要支持多种设备&#xff0c;并使用各种传感器来收集数据。您可能需要实现实时数据可视化…...

基于Qt5开发图形界面——WiringPi调用Linux单板电脑IO

Qt5——WiringPi Qt5WiringPi示例教程 Qt5 Qt是一种跨平台的应用程序开发框架。它被广泛应用于图形用户界面&#xff08;GUI&#xff09;开发&#xff0c;可以用于构建桌面应用程序、移动应用程序和嵌入式应用程序。Qt提供了丰富的功能和工具&#xff0c;使开发人员可以快速、高…...

【MySQL】组合查询

目录 一、组合查询 1.创建组合查询 2.union规则 3.包含或取消重复的行 4.对组合查询结果排序 一、组合查询 多数SQL查询都只包含从一个或多个表中返回数据的单条SELECT语句。MySQL也允许执行多个查询&#xff08;多条SELECT语句&#xff09;&#xff0c;并将结果作为单个查…...

ChatGPT:引领人机交互的未来

前言 在信息技术飞速发展的时代&#xff0c;人机交互的方式也在不断演进。技术对人们生活和工作的影响。本文将带您深入探讨一款引领人机交互未来的人工智能模型——ChatGPT。 ChatGPT简介 ChatGPT 是一种由开放AI&#xff08;OpenAI&#xff09;开发的人工智能模型&#xf…...

【算法】经典的八大排序算法

点击链接 可视化排序 动态演示各个排序算法来加深理解&#xff0c;大致如下 一&#xff0c;冒泡排序&#xff08;Bubble Sort&#xff09; 原理 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;它通过多次比较和交换相邻元素的方式&#xff0c;将…...

防溺水预警识别系统算法

防溺水预警识别系统旨在通过opencvpython网络模型深度学习算法&#xff0c;防溺水预警识别系统算法实时监测河道环境&#xff0c;对学生等违规下水游泳等危险行为进行预警和提醒。Python是一种由Guido van Rossum开发的通用编程语言&#xff0c;它很快就变得非常流行&#xff0…...

Redis 的整合 Jedis 使用

大家好 , 我是苏麟 , 今天带来 Jedis 的使用 . Jedis的官网地址&#xff1a; GitHub - redis/jedis: Redis Java client 引入依赖 <!--jedis--> <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version…...

Mainline Linux 和 U-Boot编译

By Toradex胡珊逢 Toradex 自从 Linux BSP v6 开始在使用 32位处理器的 Arm 模块如 iMX6、iMX6ULL、iMX7 上提供 mainline/upstream kernel &#xff0c;部分 64位处理器模块如 Verdin iMX8M Mini/Plus 也提供实验性支持。文章将以季度发布版本 Linux BSP V6.3.0 为例介绍如何下…...

Mycat教程+面试+linux搭建

目录 一 MyCAT介绍 二 常见的面试题总结 三 linux下搭建Mycat 一 MyCAT介绍 1.1. 什么是MyCAT&#xff1f; 简单的说&#xff0c;MyCAT就是&#xff1a; 一个彻底开源的&#xff0c;面向企业应用开发的“大数据库集群” 支持事务、ACID、可以替代Mysql的加强版数据库 一个可…...

基于工作过程的高职计算机网络技术专业课程体系构建策略

行业人才需求分析高职教育是面向地方行业培养技能型、应用型人才&#xff0c;因此&#xff0c; 在课程体系的构建上要走社会调研、构建岗位群、构建专业模块及课程设置“四步 曲”。即通过社会行业需求调查研究&#xff0c;构建岗位群&#xff0c;设置相应的专业模块&#xf…...

(笔记四)利用opencv识别标记视频中的目标

预操作&#xff1a; 通过cv2将视频的某一帧图片转为HSV模式&#xff0c;并通过鼠标获取对应区域目标的HSV值&#xff0c;用于后续的目标识别阈值区间的选取 img cv.imread(r"D:\data\123.png") img cv.cvtColor(img, cv.COLOR_BGR2HSV) plt.figure(1), plt.imshow…...

一、计算机硬件选购

计算机硬件选购 一、设备选购1.1 I/O设备1.2 机箱1.3 主板1.3.1 主板芯片组的命名方式1.3.2 主板版型1.3.3 Z790-a(DDR5)主板参数 1.4 CPU1.5 硬盘1.6 显卡1.7 内存条1.8 散热器&#xff08;水冷&#xff09;1.9 电源、风扇、网线、插线板1.9.1 电源1.9.2 风扇1.9.3 网线1.9.4 …...

Dockerfile制作LAMP环境镜像

文章目录 使用Dockerfile制作LAMP环境镜像编写Dockerfile不修改默认页面修改默认页面 Start Script目录结构及文件登录私有仓库给镜像打标签上传镜像页面检查检测镜像可用性 使用Dockerfile制作LAMP环境镜像 编写Dockerfile 不修改默认页面 FROM centos:7 MAINTAINER "…...

暴力递归转动态规划(二)

上一篇已经简单的介绍了暴力递归如何转动态规划&#xff0c;如果在暴力递归的过程中发现子过程中有重复解的情况&#xff0c;则证明这个暴力递归可以转化成动态规划。 这篇帖子会继续暴力递归转化动态规划的练习&#xff0c;这道题有点难度。 题目 给定一个整型数组arr[]&…...

debian apt error: Package ‘xxx‘ has no installation candidate

新的debian虚拟机可能会出现这个问题。 修改apt的source.list&#xff0c;位于/etc/apt/source.list&#xff0c;添加两行&#xff1a; deb http://deb.debian.org/debian bullseye main deb-src http://deb.debian.org/debian bullseye main执行&#xff1a; sudo apt-get u…...

c#设计模式-结构型模式 之 外观模式

概述 外观模式&#xff08;Facade Pattern&#xff09;又名门面模式&#xff0c;隐藏系统的复杂性&#xff0c;并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式&#xff0c;它向现有的系统添加一个接口&#xff0c;来隐藏系统的复杂性。该模式…...

Focal Loss-解决样本标签分布不平衡问题

文章目录 背景交叉熵损失函数平衡交叉熵函数 Focal Loss损失函数Focal Loss vs Balanced Cross EntropyWhy does Focal Loss work? 针对VidHOI数据集Reference 背景 Focal Loss由何凯明提出&#xff0c;最初用于图像领域解决数据不平衡造成的模型性能问题。 交叉熵损失函数 …...

运算符(个人学习笔记黑马学习)

算数运算符 加减乘除 #include <iostream> using namespace std;int main() {int a1 10;int a2 20;cout << a1 a2 << endl;cout << a1 - a2 << endl;cout << a1 * a2 << endl;cout << a1 / a2 << endl;/*double a3 …...

Qwen3-Embedding-4B广告过滤应用:恶意内容识别系统实战

Qwen3-Embedding-4B广告过滤应用&#xff1a;恶意内容识别系统实战 1. 引言&#xff1a;当广告变成“牛皮癣”&#xff0c;我们如何反击&#xff1f; 想象一下&#xff0c;你运营着一个用户社区或内容平台。每天&#xff0c;用户都在热情地分享、讨论。但总有一些不速之客&am…...

别再为GEO数据注释发愁了!三种方法(TXT/Soft/R包)保姆级代码实战

GEO数据注释实战指南&#xff1a;TXT/Soft/R包三种方法全解析 刚接触生物信息学的研究者常常会在GEO数据分析的第一步就卡壳——面对五花八门的注释文件格式&#xff0c;如何准确高效地将探针ID转换为基因Symbol&#xff1f;这个问题看似简单&#xff0c;实则暗藏玄机。我曾见过…...

C++程序员逆袭之路:手把手教你转行大模型算法岗!

作为一名C程序员&#xff0c;你拥有强大的编程能力和对底层系统深入理解的优势。然而&#xff0c;如果你对大数据、深度学习和算法设计充满热情&#xff0c;转行到大模型算法岗位可能是一个充满挑战和机遇的职业转变。本文将为你提供一份详细的转行指南&#xff0c;帮助你从C开…...

C#运动控制库大比拼:HALCON vs Leadshine,哪个更适合你的项目?

C#运动控制库深度评测&#xff1a;HALCON与Leadshine的工业级对决 在工业自动化领域&#xff0c;选择合适的运动控制库往往决定着项目的成败。作为C#开发者&#xff0c;我们常面临一个关键抉择&#xff1a;是选择功能全面的HALCON&#xff0c;还是专注运动控制的Leadshine&…...

从模型评估、梯度难题到科学初始化:一步步解析深度学习的训练问题

偏差 & 方差要理解模型的泛化能力&#xff0c;我们首先要量化它的“泛化误差”&#xff0c;即模型在未知数据上的表现。然而&#xff0c;泛化误差并非一个单一的问题&#xff0c;它源于三种不同性质的错误&#xff1a;模型固有的近似能力不足、对训练数据的过度敏感、模型数…...

告别转换限制:实测可免费批量处理Geojson、Shapefile与KML的在线工具指南

1. 为什么你需要这个免费批量转换工具&#xff1f; 作为一个经常处理地理信息数据的老手&#xff0c;我太懂你们遇到的痛点了。上周帮学弟改毕业论文&#xff0c;他用的那个知名在线转换工具&#xff0c;刚传了第4个文件就弹出"本月免费额度已用完"——这哪够用啊&am…...

微服务测试策略:端到端质量保障

微服务测试策略&#xff1a;端到端质量保障作者&#xff1a;AI测试工程师 关键词&#xff1a;微服务测试、集成测试、契约测试、端到端一、微服务测试挑战 1.1 测试金字塔变化 传统应用&#xff1a; 微服务应用&#xff1a;/\ /\/ \ / \/…...

基于高频脉冲注入法的转子初始位置辨识算法代码及其应用

基于高频脉冲注入法转子初始位置辨识算法代码&#xff0c;无感启动中最重要的便是初始位置估计&#xff0c;高频注入法无感运行的方法适用于带电机运行&#xff0c;用在初始位置检测时&#xff0c;时间不固定&#xff0c;依赖电机参数。 采用脉冲注入法后&#xff0c;检测时间固…...

OpCore-Simplify终极指南:如何快速构建完美的OpenCore EFI配置

OpCore-Simplify终极指南&#xff1a;如何快速构建完美的OpenCore EFI配置 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在为复杂的Hackintosh配置…...

掌握Dynamic-DataSource注解与事务传播:MANDATORY模式终极指南

掌握Dynamic-DataSource注解与事务传播&#xff1a;MANDATORY模式终极指南 【免费下载链接】dynamic-datasource dynamic datasource for springboot 多数据源 动态数据源 主从分离 读写分离 分布式事务 项目地址: https://gitcode.com/gh_mirrors/dy/dynamic-datasource …...