c++类【高潮】
类继承
和直接复制源代码修改相比,继承的好处是减少测试。
基类:原始类,
派生类:继承类,基于基类丰富更多内容的类。
继承一般用公有继承,class 派生类名 : public 基类名{……};
公有继承,基类的公有部分变成派生类的公有部分,基类的私有部分,还是基类的私有部分,派生类只能通过基类的公有方法和保护方法访问。这也说明,数据的安全性。一旦定义为私有,终生私有,派生出来也不会有权读取。
派生类构造函数
派生类,必须创建自己的构造函数。但是,派生类不能直接访问基类的私有数据。所以,派生类又必须使用基类的构造函数来初始化。
可曾还记得:成员初始化列表?是不是在哪见过?
只能通过这种方式给基类初始化,因为,创建派生类,要先创建基类,因为派生类包括基类数据。所以,在派生类的构造函数初始化时,要先有基类对象,所以,通过成员初始化列表法,在派生类生成前,先生成基类给派生类对象使用。
派生类析构函数
先执行派生类的构造函数,再调用基类的析构函数。
使用派生类
派生类和基类的特殊关系:派生类可以使用基类的方法(当然,只能使用基类公有的方法)。
基类指针可以指向派生类的对象,但是,反过来不行。可以这么理解,派生类是基于基类来的,派生类的东西要多一些,基类的东西少一些,这样,基类有的,派生类一定有,而派生类有的东西基类不一定用,因此,用基类指针指向派生类对象,用这个指针调用方法时,一定是能存在的。而如果用派生类指针指向基类,派生类更强大,指向的东西派生类可能没有,因此就可能出错。因此,不允许用指向派生类的指针指向基类对象,但可以用指向基类的指针指向派生类对象。
这段比较别扭,从包含可被包含的角度理解,会容易些。就像你可以是你我去父亲的儿子,但不能反过来。
多态公有继承
多态(重载)公有继承,多态就是重载,重载更好理解一些,多态有点过于抽象,不好理解。
类里为啥还有重载?主要是因为,基类的方法A,如果派生类觉得这个函数不好用,但是又不能给个新名字,因为新名字可能就没这么方便理解了,所以,派生类就定义一个和基类方法名称一样的函数,但是呢,做的内容可能就不一样了,或者做的更好了。这个时间,就在派生类的重新定义了方法A。
当然 还有另一个方法,虚函数……
好了,这里回忆一下,我们学了几个概念了:内联函数,友函数、虚函数。这些函数为什么存在呢?
内联函数:方便提升高频调用某个方法的效率,就搞了个内联函数,inline 开头。
友函数:为了不是成员函数,还可以访问类的私有数据,就搞了个友函数,friend开头。
虚函数:为了方便派生类重载方法,搞了个虚函数。
虚函数的这个方便之处在于,还记得开头说的:可以将派生类对象赋值给指向基类的指针,但反过来不行。这个规则会带来一个问题,当基类指针赋值的是派生类对象时,那么当这个指针调用一个基类和派生类都有的函数(方法)时,这个指针到底是调用基类的方法,还是派生类的方法?理论上,基类的指针指向派生的对象,指针也只是调用这个派生对象里基类的方法(因为派生对象继承基类的方法)。因此,虚函数的意义就在于,在基类指针指向派生类对象时,这个指针按指向的对象调用方法。也就是说,基类指针指向派生类对象,就调用派生对象的方法,指向基类对象,就调用基类对象的方法。
所以, 一般,基类的析构函数也定义为虚函数,能够保证派生类对象退出时,会执行完派生类析构函数后,继续执行基类的析构函数。否则基类指向派生类对象时,基类析构函数不是虚函数时,就只会调用基类的析构函数,而不会调用派生类的析构函数。
所以,之所在这么复杂,都是因为“指向基类的指针可以指向派生类对象”造成的。
静态联编和动态联编
因为“指向基类的指针可以指向派生类对象”(万恶之源),导致调用函数的时候,在编译阶段不能确认是用哪个函数,因此,只有在运行的时候才能确定,到底调用的是哪人函数,这种让编译器在运行时才选择调用函数叫动态联编。
静态联编是指在编译阶段就已知调用函数,使用静态联编。
对非虚函数使用静态联编,对于虚函数使用动态联编。
至于动态联编的实现方法,可不不必知道。
总结
如果,在派生类中要重新定义,在基类中,该方法要定义为虚函数。
构造函数不能定义为虚函数,因为不可继承。
析构函数一般要定义为虚函数。
友元函数不能是虚函数,因为友元函数不是类的成员函数。
如果重新定义了继承的方法,要确保与原型完全相同(指特征标),返回类型需要根据新的类进行修改,保持与新类一致。
如果基类的方法有重载,在派生类中,要重新定义所有的基类重载版本,否则,派生类只能调用重新定义的几个版本,其它基类的版本将被隐藏,派生类不能用没有重新定义的版本。
访问控制(protected)
忘记protected这个成员吧,就当只有public和private这两种。protected没啥好处。
抽象基类
纯虚函数?好变态,虚函数还不够,还整出来一个纯虚函数。
纯虚函数:声明虚函数原型时,直接赋值=0;就是说这个虚函数是纯虚函数。
声明 纯虚函数,不需要为类实现他,等到谁继承他时,继承他的派生类再实现他。
包含纯虚函数的基类,就是一个抽象基类。这种类,不能直接创建对象,他只能被继承。
继承和动态内存分配
派生类与new
动态内存分配就是使用new方法了。
继承类,主要考虑就是基类里使用了new方法来对成员分配空间,这个时候,继承时,如何释放基类里new开辟的内存空间,复制和,和赋值时,怎么进行深度复制,而不是执行浅复制(只复制地址,而不复制地址指向的值,导致指向多个对象指向同一个内存这种混乱)。
因此,对于基类有使用new为成员开辟内存的情况,需要考虑用个函数:
析构函数,复制构造函数,重载赋值运算符。
分两种情况:
1、派生类没有使用new为自己的成员分配内存,不需要重新定义上面3个函数。
2、派生类使用new了。必须重新定义上述3个函数。
派生类如何使用基类友元函数
第1步、通过基类的友元函数访问
第2步、通过强制类型转换,将派生类对象转换为基类对象。传递为基类对象的友元函数。
总结
1、编译器会自动创建一些公有成员函数
自动创建的函数,表明很重要
默认构造函数。(自动创建的,就啥也不做),一般建议提供默认构造函数,不要让编译器自动创建。
复制构造函数。一般有4种情况使用复制构造函数:将一个对象初始化为同类的另一个对象;按值递给函数;按值返回对象;编译器生成临时对象。如果类声明里,有使用new分配内存时,要重新定义复制构造函数。
赋值运算符。同上关注是否有new,要不要重定义。
2、其它
转换函数:将类对象转换为其它类型时要定义转换函数,一般是转换为其它基础类型,如int,float,double等。
explicit:用于转换函数和构造函数,表示不允许隐式,必须显示调用。
按值和按引用传递对象,一般建议按引用传递。一个是因为效率,一个是因为虚函数。
按值返回和按引用返回对象,一般按引用返回。
const:在一个函数头,有3个地方可以使用const。开始,中间,和结尾,不同位置,限制的目标不同。开始是限制修改返回值,中间是限制不修改传递的参数,结尾是限制这个函数不能修改对象自己的成员。
类的派生是is-a的关系。
构造函数,析构函数,赋值函数不能被继承。
相关文章:
c++类【高潮】
类继承 和直接复制源代码修改相比,继承的好处是减少测试。 基类:原始类, 派生类:继承类,基于基类丰富更多内容的类。 继承一般用公有继承,class 派生类名 : public 基类名{……}; 公有继承&…...
C++进阶--AVL树的实现续
文章目录 C进阶--AVL树的实现双旋AVL树的查找AVL树的检验结语 很高兴和搭大家见面,给生活加点impetus,开启今天的比编程之路!! 今天我们来完善AVL树的操作,为后续红黑树奠定基础!! 作者&#x…...
1 2 3 4 5顺序插入,形成一个红黑树
红黑树的特性与优点 红黑树是一种自平衡的二叉搜索树,通过额外的颜色标记和平衡性约束,确保树的高度始终保持在 O(log n)。其核心特性如下: 每个节点要么是红色,要么是黑色。根节点和叶子节点(NIL节点)是…...
Telnetlib三种异常处理方案
1. socket.timeout 异常 触发场景 网络延迟高或设备响应缓慢,导致连接或读取超时。 示例代码 import telnetlib import socketdef telnet_connect_with_timeout(host, port23, timeout2):try:# 设置超时时间(故意设置较短时间模拟超时)tn…...
Linux:进程间通信---消息队列信号量
文章目录 1.消息队列1.1 消息队列的原理1.2 消息队列的系统接口 2. 信号量2.1 信号量的系统调用接口 3. 浅谈进程间通信3.1 IPC在内核中数据结构设计3.2 共享内存的缺点3.3 理解信号量 序:在上一章中,我们引出了命名管道和共享内存的概念,了解…...
暗物质卯引力挂载技术
1、物体质量以及其所受到的引力约束(暗物质压力差) 自然界的所有物体,其本身都是没有质量的。我们所理解的质量,其实是物体球周空间的暗物质对物体的挤压,压力差。 对于宇宙空间中的单个星球而言,它的球周各处压力是相同的,所以,它处于平衡状态,漂浮在宇宙中。 对于星…...
JMeter 中实现 双 WebSocket(双WS)连接
在 JMeter 中实现 双 WebSocket(双WS)连接 的测试场景(例如同时连接两个不同的 WebSocket 服务或同一服务的两个独立会话),可以通过以下步骤配置: 1. 场景需求 两个独立的 WebSocket 连接(例如 …...
卡尔曼滤波算法简介与 Kotlin 实现
一、引言 卡尔曼滤波(Kalman Filter)是一种基于线性系统状态空间模型的最优递归估计算法,由鲁道夫・E・卡尔曼于 1960 年提出。其核心思想是通过融合系统动态模型预测值与传感器观测值,在最小均方误差准则下实现对系统状态的实时…...
【比赛真题解析】混合可乐
这次给大家分享一道比赛题:混合可乐。 洛谷链接:U561549 混合可乐 【题目描述】 Jimmy 最近沉迷于可乐中无法自拔。 为了调配出他心目中最完美的可乐,Jimmy买来了三瓶不同品牌的可乐,然后立马喝掉了一些(他实在是忍不住了),所以 第一瓶可口可乐最大容量为 a 升,剩余 …...
[论文阅读]BadPrompt: Backdoor Attacks on Continuous Prompts
BadPrompt: Backdoor Attacks on Continuous Prompts BadPrompt | Proceedings of the 36th International Conference on Neural Information Processing Systems 36th Conference on Neural Information Processing Systems (NeurIPS 2022) 如图1a,关注的是连续…...
DeepSeek 实现趣味心理测试应用开发教程
一、趣味心理测试应用简介 趣味心理测试是一种通过简单的问题或互动,为用户提供心理特征分析的方式。它通常包含以下功能: 测试题目展示:以问答形式呈现心理测试题。用户行为分析:根据用户的回答或选择,分析心理特征…...
计算机网络八股文--day1
从浏览器输入url到显示主页的过程? 1. 浏览器查询域名的IP地址 2. 浏览器和服务器TCP三次握手 3. 浏览器向服务器发送一个HTTP请求 4. 服务器处理请求,返回HTTP响应 5. 浏览器解析并且渲染页面 6. 断开连接 其中使用到的协议有DNS协议(…...
【计算机视觉】OpenCV实战项目:FunnyMirrors:基于OpenCV的实时哈哈镜效果实现技术解析
FunnyMirrors:基于OpenCV的实时哈哈镜效果实现技术解析 1. 项目概述2. 技术原理2.1 图像变形基础2.2 常见的哈哈镜变形算法2.2.1 凸透镜效果2.2.2 凹透镜效果2.2.3 波浪效果 3. 项目实现细节3.1 核心代码结构3.2 主要功能实现3.2.1 图像采集3.2.2 变形映射生成3.2.3…...
量子机器学习:下一代AI的算力革命与算法范式迁移——从量子神经网络到混合量子-经典架构的产业落地
一、引言:当AI遇见量子力学 2025年,全球量子计算市场规模突破200亿美元,而量子机器学习(QML)正以370%的年复合增长率(数据来源:Gartner 2024)成为最受关注的技术融合领域。传统深度…...
【数据结构】——栈
一、栈的概念和结构 栈其实就是一种特殊的顺序表,其只允许在一端进出,就是栈的数据的插入和删除只能在一端进行,进行数据的插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的元素遵循先进后出LIFO(Last InFirst O…...
Octave 绘图快速入门指南
目录 1. 基本的 2D 绘图 2. 自定义图形样式 3. 绘制散点图 4. 绘制柱状图 5. 绘制直方图 6. 3D 绘图 6.6.1 3D 曲面图 6.6.2 3D 散点图 7. 绘制极坐标 8. 多子图绘制 总结 Octave 是一个类似于 MATLAB 的开源数学软件,广泛用于数值计算和数据分析。它提供…...
RabbitMQ深入学习
继续上一节的学习,上一节学习了RabbitMQ的基本内容,本节学习RabbitMQ的高级特性。 RocketMQ的高级特性学习见这篇博客 目录 1.消息可靠性1.1生产者消息确认1.2消息持久化1.3消费者消息确认1.4消费失败重试机制1.5消息可靠性保证总结 2.什么是死信交换机…...
数据结构中的栈与队列:原理、实现与应用
前言:栈和队列是计算机科学中两种最基础的线性数据结构,它们的独特操作规则和广泛的应用场景使其成为每一位开发者必须掌握的核心知识。本文将通过生活案例、代码实现和实际应用场景,带您深入理解这两种数据结构的精髓。 1.栈(Sta…...
Android 13 默认打开 使用屏幕键盘
原生设置里,系统-语言和输入法-实体键盘-使用屏幕键盘 选项, 关闭时,外接物理键盘,如USB键盘,输入时不会弹出软键盘。 打开时,外接物理键盘,如USB键盘,输入时会弹出软键盘。 这个选…...
C++GO语言微服务之图片、短信验证码生成及存储
目录 01 session的处理 02 获取网页图片验证码ID 03 测试图片验证码 04 图片验证码模块集成 05 图片验证码功能移植微服务 06 图片验证码功能对接微服务的web实现 07 对接微服务的web实现步骤小结 08 Redis数据库基本操作回顾 09 go语言操作Redis数据库API介绍 10 go语…...
视觉革命来袭!ComfyUI-LTXVideo 让视频创作更高效
探索LTX-Video 支持的ComfyUI 在数字化视频创作领域,视频制作效果的提升对创作者来说无疑是一项重要的突破。LTX-Video支持的ComfyUI便是这样一款提供自定义节点的工具集,它专为改善视频质量、提升生成速度而开发。接下来,我们将详细介绍其功…...
MySQL 索引(一)
文章目录 索引(重点)硬件理解磁盘盘片和扇区定位扇区磁盘的随机访问和连续访问 软件方面的理解建立共识索引的理解 索引(重点) 索引可以提高数据库的性能,它的价值,在于提高一个海量数据的检索速度。 案例…...
认识 Linux 内存构成:Linux 内存调优之内存分配机制和换页行为认知
写在前面 博文内容涉及 Linux 中内存分配和换页机制的基本认知理解不足小伙伴帮忙指正 😃,生活加油99%的焦虑都来自于虚度时间和没有好好做事,所以唯一的解决办法就是行动起来,认真做完事情,战胜焦虑,战胜那些心里空荡荡的时刻,而不是选择逃避。不要站在原地想象困难,行…...
uniapp-商城-50-后台 商家信息
本文介绍了如何在后台管理系统中添加和展示商家信息,包括商家logo、名称、电话、地址和介绍等内容,并支持后期上传营业许可等文件。通过使用uni-app的uni-forms组件,可以方便地实现表单的创建、校验和管理操作。文章详细说明了组件的引入、页…...
汇编语言的温度魔法:单总线温度采集与显示的奇幻之旅
在嵌入式系统的奇妙世界中,汇编语言与硬件的结合总是充满了无限可能。今天,我将带你走进一场充满乐趣的实验:如何用汇编语言在单片机上实现单总线温度采集与显示。这不仅是一次技术探索,更是一场点亮创意与灵感的奇幻之旅…...
2025盘古石初赛WP
来不及做,还有n道题待填坑 文章目录 手机取证 Mobile Forensics分析安卓手机检材,手机的IMSI是? [答案格式:660336842291717]养鱼诈骗投资1000,五天后收益是? [答案格式:123]分析苹果手机检材&a…...
巡检机器人数据处理技术的创新与实践
摘要 随着科技的飞速发展,巡检机器人在各行业中逐渐取代人工巡检,展现出高效、精准、安全等显著优势。当前,巡检机器人已从单纯的数据采集阶段迈向对采集数据进行深度分析的新阶段。本文探讨了巡检机器人替代人工巡检的现状及优势,…...
MySQL的Order by与Group by优化详解!
目录 前言核心思想:让索引帮你“排好序”或“分好组”Part 1: ORDER BY 优化详解1.1 什么是 Filesort?为什么它慢?1.2 如何避免 Filesort?—— 利用索引的有序性1.3 EXPLAIN 示例 (ORDER BY) Part 2: GROUP BY 优化详解2.1 什么是…...
使用小丸工具箱(视频压缩教学)压缩7倍
我们日常经常会遇见视频录制或者剪辑视频生成之后,视频文件非常占用存储空间,那么这款开源工具可以帮助我们压缩7倍,而且视频质量依然清晰。 软件下载 ①:可以通过我分享的CSDN资源下载:https://download.csdn.net/d…...
ui组件二次封装(vue)
组件二次封装的意义 保证一个系统中ui风格和功能的一致性便于维护 从属性、事件、插槽、ref这几方面考虑 属性和事件的处理:ui组件上绑定$attrs(v-model本质也是一个属性加一个事件,所以也在其列) 在自定义组件中打印$attrs&am…...
利用大型语言模型有效识别网络威胁情报报告中的攻击技术
摘要 本研究评估了网络威胁情报(CTI)提取方法在识别来自网络威胁报告中的攻击技术方面的性能,这些报告可从网络上获取,并使用了 MITRE ATT&CK 框架。我们分析了四种配置,这些配置利用了最先进的工具,包…...
笔试模拟 day4
观前提醒: 笔试所有系列文章均是记录本人的笔试题思路与代码,从中得到的启发和从别人题解的学习到的地方,所以关于题目的解答,只是以本人能读懂为目标,如果大家觉得看不懂,那是正常的。如果对本文的某些知…...
TCP的连接管理
三次握手 什么是三次握手? 1. 第一次握手(客户端 → 服务器) 客户端发送一个 SYN 报文,请求建立连接。 报文中包含一个初始序列号 SEQ x。 表示:我想和你建立连接,我的序列号是 x。 2. 第二次握手&a…...
ffmpeg 写入avpacket时候,即av_interleaved_write_frame方法是如何不需要 业务层释放avpacket的 逻辑分析
我们在通过 av_interleaved_write_frame方法 写入 avpacket的时候,通常不需要关心 avpacket的生命周期。 本文分析一下内部实现的部分。 ----> 代表一个内部实现。 A(){ B(); C(); } B(){ D(); } 表示为: A ---->B(); ---->D(); ---->C(); int…...
【MyBatis-7】深入理解MyBatis二级缓存:提升应用性能的利器
在现代应用开发中,数据库访问往往是性能瓶颈之一。作为Java生态中广泛使用的ORM框架,MyBatis提供了一级缓存和二级缓存机制来优化数据库访问性能。本文将深入探讨MyBatis二级缓存的工作原理、配置方式、使用场景以及最佳实践,帮助开发者充分利…...
扫雷革命:矩阵拓扑与安全扩散的数学之美
目录 扫雷革命:矩阵拓扑与安全扩散的数学之美引言第一章 雷区生成算法1.1 组合概率模型1.2 矩阵编码体系第二章 数字计算系统2.1 卷积核运算2.2 边缘处理第三章 安全扩散机制3.1 广度优先扩散3.2 记忆化加速第四章 玩家推理模型4.1 线性方程组构建4.2 概率决策模型第五章 高级…...
通俗的桥接模式
桥接模式(Bridge Pattern) 就像一座桥,把两个原本独立变化的东西连接起来,让它们可以各自自由变化,互不干扰。简单来说,就是 “把抽象和实现分开,用组合代替继承”。 一句话理解桥接模式 假设你…...
金丝猴食品:智能中枢AI-COP构建全链路数智化运营体系
“金丝猴奶糖”,这个曾藏在无数人童年口袋里的甜蜜符号,如今正经历一场数智焕新。当传统糖果遇上数字浪潮,这家承载着几代人味蕾记忆的企业,选择以数智化协同运营平台为“新配方”,将童年味道酿成智慧管理的醇香——让…...
基于定制开发开源AI智能名片S2B2C商城小程序的公私域流量融合运营策略研究
摘要:本文以定制开发开源AI智能名片S2B2C商城小程序为技术载体,系统探讨公域流量向私域流量沉淀的数字化路径。研究通过分析平台流量(公域流量)与私域流量的共生关系,提出"公域引流-私域沉淀-数据反哺"的闭环…...
一、数据仓库基石:核心理论、分层艺术与 ETL/ELT 之辨
随着企业数据的爆炸式增长,如何有效地存储、管理和分析这些数据,从中提炼价值,成为现代企业的核心竞争力之一。数据仓库 (Data Warehouse, DW) 正是为此而生的关键技术。理解其基础理论对于构建高效的数据驱动决策体系至关重要。 一、数据库…...
智慧能源大数据平台建设方案(PPT)
1、建设背景 2、建设思路 3、建设架构 4、应用场景 5、展望 软件开发全方位管理资料包清单概览: 任务部署指令书,可行性研究报告全集,项目启动审批文件,产品需求规格详尽说明书,需求调研策略规划,用户调研问…...
递归函数(斐波那契数列0,1,1,2,3,5,8,13,21,34,55...)
目录 一、斐波那契数列(兔子问题) 二、迭代法(用while循环推下一项 ) 三、递归函数 (函数的定义中调用函数自身的一种函数定义方式) 四、递归函数的底层逻辑推理 (二叉树推倒最左下节点回退法) 一、斐波那契数列(兔子问题&…...
Python 从 SQLite 数据库中批量提取图像数据
Python 从 SQLite 数据库中批量提取图像数据 flyfish 实现了一个可扩展的 SQLite 图像导出工具,能够自动检测图像格式、处理数据前缀,并将数据库中的二进制图像数据导出为文件系统中的标准图像文件 import os import sqlite3 from typing import Dict…...
rust-candle学习笔记12-实现因果注意力
参考:about-pytorch 定义结构体: struct CausalAttention {w_qkv: Linear,dropout: Dropout, d_model: Tensor,mask: Tensor,device: Device, } 定义new方法: impl CausalAttention {fn new(vb: VarBuilder, embedding_dim: usize, ou…...
vue3使用tailwindcss报错问题
npm create vitelatestnpm install -D tailwindcss postcss autoprefixernpx tailwindcss init 4. 不过执行 npx tailwindcss init 的时候控制台就报错了PS E:\vite-demo> npx tailwindcss init npm ERR! cb.apply is not a function npm ERR! A complete log of this run c…...
MySQL COUNT(*) 查询优化详解!
目录 前言1. COUNT(*) 为什么慢?—— InnoDB 的“计数烦恼” 🤔2. MySQL 执行 COUNT(*) 的方式 (InnoDB)3. COUNT(*) 优化策略:快!准!狠!策略一:利用索引优化带 WHERE 子句的 COUNT(*) (最常见且…...
5.Redission
5.1 前文锁问题 基于 setnx 实现的分布式锁存在下面的问题: 重入问题:重入问题是指 获得锁的线程可以再次进入到相同的锁的代码块中,可重入锁的意义在于防止死锁,比如 HashTable 这样的代码中,他的方法都是使用 sync…...
RAG 赋能客服机器人:多轮对话与精准回复
一、引言 在人工智能技术飞速发展的今天,客服机器人已成为企业提升服务效率的重要工具。然而,传统客服系统在多轮对话连贯性和精准回复能力上存在明显短板。检索增强生成(Retrieval-Augmented Generation, RAG)技术通过结合大语言…...
rust-candle学习笔记13-实现多头注意力
参考:about-pytorch 定义结构体: use core::f32;use candle_core::{DType, Device, Result, Tensor}; use candle_nn::{embedding, linear_no_bias, linear, ops, Dropout, Linear, Module, VarBuilder, VarMap};struct MultiHeadAttention {w_qkv: Li…...
PyTorch API 5 - 全分片数据并行、流水线并行、概率分布
文章目录 全分片数据并行 (FullyShardedDataParallel)torch.distributed.fsdp.fully_shardPyTorch FSDP2 (fully_shard) Tensor Parallelism - torch.distributed.tensor.parallel分布式优化器流水线并行为什么需要流水线并行?什么是 torch.distributed.pipelining&…...