基于python的深度学习框架有_《用Python实现深度学习框架》上市-程序员宅基地

技术标签: 基于python的深度学习框架有  

朋友们,《用Python实现深度学习框架》已经由人民邮电出版社出版上市了。在这本书中,我们带领读者仅用Python+Numpy实现一个基于计算图的深度学习框架MatrixSlow。本书讲解了计算图、自动求导、优化算法等框架核心功能的原理与实现,介绍了逻辑回归、全连接神经网络、FM、Wide & Deep、DeepFM、RNN、CNN等多种典型模型和网络的原理与应用,尤其注重各种模型背后的思想、联系与演化发展。我们用MatrixSlow搭建并训练了这些模型。

本书是一本关于深度学习模型和框架原理的入门书籍,低门槛但是高上限,面向任何对机器学习和深度学习的原理与实现感兴趣的读者。读者无需任何前导知识(可能需要熟悉一门面向对象编程语言,比如Python),通过阅读本书即可达到对深度学习核心主干知识的较深刻的理解。

实物:外观内容

前言:

理查德·费恩曼(Richard Feynman)教授去世后,人们在他的黑板上发现了What I cannot create, I do not understand 这句话。其实,费恩曼教授的本意是:除非你能由基本原理推导出某个结论,否则就没有真正理解它。记结论或背公式是没有用的,只有从一张白纸开始一步步地将结论构建出来,你才是真正理解了一个理论或一个事物。

在机器学习领域,特别是在神经网络和深度学习范畴内,模型和网络数量众多,各种超参数也是名目繁多。特别是当人们应用深度神经网络时,又会针对具体问题的特点提出许多特殊的网络结构。但是我们必须看到,这些眼花缭乱的模型和网络并非彼此孤立,它们之间存在着密切的联系和连续的发展演化路径。

如果将一个领域的知识比作一棵大树,那么我们对它的认识过程不应该是从外向里、从顶向下的,不应该只满足于认识并记住它那繁多的树叶。初学者往往会陷入茴字四种写法式的误区,并且以知道各种模型、各个网络为荣,从而陷入概念和术语的迷宫却看不到它们之间存在的更深刻的联系。总而言之,要想认识一棵树,从树冠开始一片一片认识每个树叶无疑是效率低下的。

更重要的是,通过这种方式根本无法达到真正理解。我们应该从树根出发,沿着树干向上,并尝试重新构建整棵树。在此期间,可以在某个树枝的根部就停下来,因为那时会发现,剩下的细枝末节(字面意思)已经不再重要了,只要在需要的时候再查看那个分支就行了。总之,要想真正地理解(understand)一个领域,就必须能从基本原理出发重新建造(create)它们,最终你会具备统一的、非碎片化的眼光。

程序员爱说一句话:不要重复造轮子。在工作和生产中的确不应该重复造轮子,但在学习和理解的过程中却需要重复。费恩曼教授的黑板上还有一句话:Know how to solve every problem that has been solved(应该知道每一个已被解决的问题的解决方法)。许多教师都会强调习题的重要性,这是对的。在座的诸位“做题家”对此自然也体会深刻。但费恩曼教授更高一筹,他所传达的思想是做题不是目的,目的是教人学会自己动手构造。光看明白是不够的,只有会造轮子才能改进轮子;只有会解有答案的问题,才能去解决还没有答案的问题。其实,这仍然是理解与建造的关系。

1984 年,《现代操作系统》(俗称马戏团书)的作者塔嫩鲍姆教授(Andrew S. Tanenbaum)开发了一个教学用的操作系统Minix。受其启发(多大程度未知),Linus Torvalds 创造了Linux系统。这里我们决定效仿前辈,带领读者用Python 语言从零开始实现一个基于计算图的机器学习/深度学习框架,我们称其MatrixSlow。取这个谦卑的名字是为了表明它只是一个用于教学的框架。若在座诸君中有哪位能受其启发并创造一个专业的深度学习框架,我们将深感欣慰。

计算图是一个强大的工具,用它可以搭建并训练从简单的线性回归、逻辑回归到复杂的深度神经网络等一大类机器学习模型。计算图通过自动求导和梯度下降法,以统一的方式给这一类机器学习模型提供了训练算法。因此,实现了计算图也就等于实现了大部分机器学习算法。看过本书的第二部分,读者将会对这一点有所感受。

在一步步带领读者实现计算图框架的同时,我们还介绍了机器学习、模型、训练等相关概念和原理(我们假设所有读者都没有前导知识,完全从空白讲起)。此外,本书以相当大的篇幅介绍了线性模型、逻辑回归、多层全连接神经网络、非全连接深度神经网络、循环神经网络和卷积神经网络等模型的原理和结构,并且尤其注重它们之间的联系。读者会看到,动机和思路是如何被反复应用并逐渐发展的。我们还以一些实际问题为例展示了这些模型的应用。最后,我们讨论了一些工程方面的问题,例如模型的保存与服务、分布式训练以及要想实现专业级深度学习框架还需应对的若干问题。

虽然本书的主旨为理解与建造,但是通过建造达成理解才是关键。时常会有朋友问:“是否有必要亲手实现模型?”必要与否很难界定,这取决于想要实现模型的人的目的和工作层次(这里的层次并无高低褒贬之意)。所以,我们不谈目的与必要性,只谈亲手实现模型的好处。以我的浅见以及亲身经历来看,亲手实现模型极其有助于夯实理解。在动手实现模型的过程中,你不得不把对理论的理解厘清到最细微处,这里容不得半点含糊。

更重要的是,当自己实现的模型运转起来,应用于实际问题以测试其正确性时,现实会逼迫你反复测试,这个过程可以极大地帮助你加深对于模型行为的理解。作为程序员,测试本来是一件在概念上简单明确的事情。在设计程序的时候,预测有如此这般的输出,它就应该有如此这般的输出。一个断言(assert),过就是过,不过就是不过。但是在机器学习领域,这个范式就会有一定程度上的失效。

我们知道,模型(起码本书讨论的这类模型)的训练是一个近似迭代优化的过程,其中到处存在随机性:参数的随机初始化,样本的随机洗牌(shuffle)以及一些例如Drop Out 之类引入随机性的正则化方法等,都会带来不确定性。训练的结果,比如模型参数、损失和评价指标等,都只具有统计意义。更重要的是,模型在样本集上的损失取决于问题本身,我们不可能知道这个高维函数的真实“地形”。基于梯度的优化算法也不能保证可以找到全局最优点。全局最优点可能根本就不存在或者存在但不唯一。所以,模型训练根本没有严格的正确与否一说。

但是,模型的实现总有对错。错的实现在各个测试问题上都不会有好的表现。简单来说,好的表现就是随着训练的进行,损失值降低而指标上升。但是,受制于问题本身、模型结构以及超参数,对的实现有时也未见得会有好表现,或者好表现的现象需要很久才能显现。这迫使实现者必须反复在各类问题上验证自己的实现,尝试各种模型结构和超参数的组合,这是一个永无终点的过程。实现者对自己的实现的信心会随着无数次尝试而逐渐坚定。更为宝贵的是,所有的这些操作和观察都能帮助实现者建立起对模型行为的认知和直觉。

我们知道,结构和超参数控制着模型的自由度,自由度又决定了模型的偏差-方差权衡,进而影响了模型的过拟合/欠拟合。在物理学中,一套完整的约束可将动力系统的自由度降低一个整数值。由此,之后就可以用数量更少的广义坐标表示该系统。类比到模型训练,正则化方法施加的约束并不是完整的,模型的自由度也不是整数。狭义的正则化之外的超参数,乃至模型结构,都在以复杂的方式影响着模型的自由度。我们常说调参,就是以一种经验的、半猜半试的方式控制模型自由度,以改进模型的表现。当然,我们还有相对蛮力的网格搜索和随机搜索,以及一些非参数优化算法,如遗传、贝叶斯等,但是它们都需要较大的计算量,使得我们在大部分时候难以承受。

了解每一个超参数的原理和含义,以及它们对自由度的大致影响,是建模工程师的必备能力。各种超参数在具体问题、具体模型上究竟会以什么形式产生什么影响,只有经过观察和经验的积累才能形成认识。实现并验证模型的过程,就是一个密集经历这种观察和经验积累的过程。在复杂的科学和技术领域,亲身经历与体验是必不可少的,这是一个经历生命的过程。魔鬼梅菲斯特曾对拜访浮士德博士的青年学生说:“理论是灰色的,而生命之树长青。”

既然说到了理论,这又是一个机器学习领域与程序员熟悉的其他领域不同的地方。实现和应用机器学习必须要理解其原理,而阅读其他领域的源代码时,只要把代码读透也就彻底理解了。你也许会这样想,在完全知道内存、总线和CPU 中发生的每一件事后,我难道还不能理解这个程序在干什么吗?对于机器学习来说,这还真不够。比如,你在某处看到了一个计算,但是这里为什么要计算?计算的目的是什么?为什么有效?这些可不是代码能告诉你的。“读代码”原本是程序员了解一个东西的终极大招,但是在机器学习这里又失效了。

有种常见的说法是把公式推一遍。理解机器学习的数学原理可不能只是简单地“推公式”,而应该要理解公式究竟说了什么。当然,在初学时能够把公式推导的每一步都弄明白就已经不易了。但是如果把注意力都集中到推导,又容易使人难以看清这些公式究竟表达了什么。这就好比虽然踩着脚印亦步亦趋,最后确实也走到了目的地,但始终没有抬头看清这是什么路,目的地是哪里,为什么走这条路,而这些才是最重要的。人们总是希望(妄想)生活中不要有数学。实际上,所谓数学和非数学,无非都是在说事说理而已。要想把事情说得精确深刻,就必须把相关的量以及量之间的关系说清楚,而数学就是简洁地表达这些关系的一种手段。

由于本书面向的是初学者,因此在数学上没有搞得太深入、太复杂。我们会尽力阐述,以帮助读者掌握机器学习的数学所说的“事”是什么,也就是“推公式”时容易看不清的那些东西。本书不避讳使用公式,因为在必要时这是必不可少的,但量确实不大。我们把一些较为高级的主题放在了灰色的选读框中。读者可以根据实际需要选择是否略过这些高级主题,而不至于干扰阅读。记住,数学永远都是必要的。本书在数学上简单了,则必然不够深刻。鉴于此,读者可以参考本书的姊妹篇《深入理解神经网络:从逻辑回归到CNN》①,那里有更完整的数学。

内容概览

本书分为三个部分。第一部分是原理篇,包含第1 章至第3 章。其中,第1 章介绍机器学习的基本概念,引入了一个简单的线性模型ADALINE,这一章介绍的概念贯穿本书。第2 章介绍计算图,其核心内容是计算图的原理、梯度下降法以及计算图上的自动求导。第3 章介绍梯度下降法的各种变体。在前三章中,我们带领读者实现MatrixSlow 框架的核心基础设施,并在此过程中渗透讲解基础原理和概念。

第二部分是模型篇。有了基础设施,我们就可以搭建各种模型了。本部分包括第4 章至第8章。其中,第4 章介绍逻辑回归,第5 章介绍多层全连接神经网络,第6 章介绍几种非全连接神经网络,第7 章介绍循环神经网络,第8 章介绍卷积神经网络。这些模型/网络的选择和顺序不是任意的。我们的想法是由简到繁、由浅至深地介绍其动机和思路的发展演变,使读者看到这些典型的、常用的模型/网络之间的联系。虽然原则上读者可以按照兴趣选读这些章节,但是我们还是建议大家能按顺序阅读,特别是第4 章和第5 章。模型虽然简单,但它们是后续一切复杂延伸的基础和出发点。

第三部分是工程篇。在这一部分中,我们将讨论一些与深度学习框架相关的工程问题。本部分包括第9 章至第12 章。其中,第9 章对训练逻辑做进一步封装,并讨论模型评估;第10 章介绍模型的保存、导入和服务部署;第11 章介绍分布式训练,在大数据和深度学习时代,样本量和网络规模都是巨大的,这些使得分布式训练必不可少;第12 章简单讨论要实现一个专业级的深度学习框架还需面对和处理的一些问题。

读者对象

本书的目标读者是对机器学习,特别是神经网络与深度学习的原理和实现感兴趣的工程师、学生以及其他各行业人士。我们不预设读者有任何与机器学习相关的前导知识,完全从零讲起(但愿能达到效果)。需要读者具有基础的编程知识,否则难以阅读书中的代码。

MatrixSlow 框架以Python 语言实现,而Python 语法简单,因此相信读者即便没有Python 经验,只要具备基础的编程能力也能读懂。我们使用Python 的线性代数库Numpy 存储矩阵并进行矩阵运算。书中的代码都是自明的,且有丰富的注释,读者不需要事先掌握Numpy 也能读懂。代码中还有对其他一些库的少量、零星的使用,它们都不会给理解代码造成障碍。

如前面所说,本书不“数树叶”,也不深究茴字的多种写法,并非一本神经网络与深度学习的模型大全。MatrixSlow 框架旨在教学,用实现来帮助读者理解原理。它虽然可以运用于一些小问题,但还远不是一个专业的深度学习框架。在对数学原理的讲解方面,本书试图抓住本质和精髓,但是考虑本书的层次,还有许多深刻的内容没有涉及。

代码资源

本书代码可至图灵社区(首页-图灵社区)本书主页“随书下载”中免费注册下载。另外,本书作者在知乎开设了专栏“计算主义”,以后会继续在专栏中讨论和分享相关主题。鉴于作者水平有限,错误难免,欢迎读者来信指正,邮箱是[email protected]

本书第1、2、4、5、6、7 和8 章由张觉非撰写。第3、9、10、11 和12 章由陈震撰写。

目录:

第一部分 原理篇

第1章 机器学习与模型 2

1.1 模型 2

1.2 参数与训练 4

1.3 损失函数 9

1.4 计算图的训练 10

1.5 小结 12

第2章 计算图 13

2.1 什么是计算图 13

2.2 前向传播 14

2.3 函数优化与梯度下降法 18

2.4 链式法则与反向传播 29

2.5 在计算图上执行梯度下降法 36

2.6 节点类及其子类 36

2.7 用计算图搭建ADALINE并训练 44

2.8 小结 48

第3章 优化器 49

3.1 优化流程的抽象实现 49

3.2 BGD、SGD和MBGD 53

3.3 梯度下降优化器 58

3.4 朴素梯度下降法的局限 60

3.5 冲量优化器 61

3.6 AdaGrad优化器 62

3.7 RMSProp优化器 64

3.8 Adam优化器 65

3.9 小结 68

第二部分 模型篇

第4章 逻辑回归 70

4.1 对数损失函数 70

4.2 Logistic函数 73

4.3 二分类逻辑回归 75

4.4 多分类逻辑回归 78

4.5 交叉熵 81

4.6 实例:鸢尾花 85

4.7 小结 88

第5章 神经网络 90

5.1 神经元与激活函数 90

5.2 神经网络 95

5.3 多层全连接神经网络 99

5.4 多个全连接层的意义 101

5.5 实例:鸢尾花 108

5.6 实例:手写数字识别 110

5.7 小结 116

第6章 非全连接神经网络 117

6.1 带二次项的逻辑回归 117

6.2 因子分解机 124

6.3 Wide & Deep 132

6.4 DeepFM 137

6.5 实例:泰坦尼克号幸存者 141

6.6 小结 150

第7章 循环神经网络 151

7.1 RNN的结构 151

7.2 RNN的输出 152

7.3 实例:正弦波与方波 155

7.4 变长序列 159

7.5 实例:3D电磁发音仪单词识别 164

7.6 小结 167

第8章 卷积神经网络 168

8.1 蒙德里安与莫奈 168

8.2 滤波器 170

8.3 可训练的滤波器 176

8.4 卷积层 183

8.5 池化层 186

8.6 CNN的结构 189

8.7 实例:手写数字识别 190

8.8 小结 194

第三部分 工程篇

第9章 训练与评估 196

9.1 训练和Trainer训练器 196

9.2 评估和Metrics节点 202

9.3 混淆矩阵 204

9.4 正确率 204

9.5 查准率 206

9.6 查全率 206

9.7 ROC曲线和AUC 208

9.8 小结 211

第10章 模型保存、预测和服务 212

10.1 模型保存 213

10.2 模型加载和预测 216

10.3 模型服务 216

10.4 客户端 222

10.5 小结 223

第11章 分布式训练 224

11.1 分布式训练的原理 224

11.2 基于参数服务器的架构 230

11.3 Ring AllReduce原理 241

11.4 Ring AllReduce架构实现 248

11.5 分布式训练性能评测 257

11.6 小结 259

第12章 工业级深度学习框架 261

12.1 张量 262

12.2 计算加速 263

12.3 GPU 265

12.4 数据接口 266

12.5 模型并行 266

12.6 静态图和动态图 267

12.7 混合精度训练 268

12.8 图优化和编译优化 270

12.9 移动端和嵌入式端 270

12.10 小结 271

推荐:

这是一本引人入胜的书,它通过由浅入深的讲解让你了解深度学习的原理、模型和实现方法,内容清晰易懂,表达生动形象。当从零开始一步一步实现一个深度学习框架MatrixSlow,你会更加深入地理解深度学习的奥秘,进而快速提升自己的能力。

—— @邱锡鹏,复旦大学计算机学院教授

深度学习框架是算法原理和工程系统相结合的产物。业界知名的框架,如TensorFlow, PyTorch等,动辄十万行的代码令想了解其内部机制的朋友望而却步。因此,对大多数人来说,深度学习框架仍充满神秘气息。我们团队做了好几年深度学习框架研发,一直苦于没有好的入门教材。现在终于有一本书把深度学习框架的工作原理通俗易懂地讲了出来。本书是一本诚意满满的作品。作者用Python实现了一个麻雀虽小但五脏俱全的深度学习框架MatrixSlow,把原理与实现一网打尽,使读者可以对深度学习框架的内核有较全面的了解。如果想进一步探索工业级项目,本书也是一个很好的起点。

——袁进辉,一流科技创始人、CEO

本书以浅显易懂的方式介绍了深度学习背后的理论。书中出现的公式不多,而是尽力以形象化的方式描述深度学习的数学原理,非常适合对理解数学公式有恐惧症的朋友阅读。同时,本书提供并详解了一个完全用Python实现的比较完整的、现代化的深度学习框架,手把手地帮助读者理解深度学习框架的实现细节。可以说,在这本书的帮助下,读者可以用类似搭积木、玩乐高的方式,边玩边学,实现一个深度学习框架。本书倡导“通过建造来促进理解”的学习理念。对于复杂难懂的概念,除非亲手实现,否则很难真正理解掌握。我非常赞同这个理念,很高兴作者把这个建造与理解的过程分享出来,为众多对这个领域感兴趣的朋友提供参考。

——赵勇,格灵深瞳创始人、CEO

在AI时代,深度学习框架层出不穷,教大家使用各种框架的书籍也并不稀缺。但是本书独树一帜,它如抽丝剥茧般为读者刨析了深度学习框架的各个功能模块,如计算图、自动求导、优化算法、分布式训练、模型管理等,并介绍了基于计算图的多种机器学习模型的原理和应用。本书提供了框架本身和构建各类模型的代码,既深入核心原理,又浅显易懂。所谓“不能创造,无法理解”,相信通过自己打造一个深度学习框架,读者可以更深入地理解其中的原理。愿大家更懂AI!

——邓亚峰,奇虎360集团副总裁、人工智能研究院院长

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39940901/article/details/111841851

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签