Skip to content

Commit 9730797

Browse files
committed
Updated to Chapter 11, Section 2
1 parent 5dc6e23 commit 9730797

37 files changed

+387
-184
lines changed

Structure.md

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -276,11 +276,11 @@
276276

277277
以求阶乘为例,讲讲函数递归是怎么一回事。
278278

279-
### 函数模版简介
279+
### 函数模板简介
280280

281-
谈谈为什么要用函数模版。不往深里讲。
281+
谈谈为什么要用函数模板。不往深里讲。
282282

283-
用函数模版写一个`max`函数,看看效果。
283+
用函数模板写一个`max`函数,看看效果。
284284

285285
## 复合类型及其使用
286286

@@ -621,7 +621,7 @@
621621

622622
对应C++中的**对象****成员**的关系,比如**一个人****心脏****大脑**
623623

624-
#### 模版与实例(instance-of relationship)
624+
#### 模板与实例(instance-of relationship)
625625

626626
对应C++中的******对象**的关系,比如**人类****张三****李四**
627627

@@ -715,61 +715,61 @@
715715

716716
#### 效果演示
717717

718-
## 模版(Template)与泛型编程基础
718+
## 模板(Template)与泛型编程基础
719719

720-
### 函数模版
720+
### 函数模板
721721

722722
#### 什么是泛型?
723723

724724
我们可以忽略它的具体类型,用一套普适的方法来处理各种类型的数据。
725725

726-
#### 如何使用函数模版
726+
#### 如何使用函数模板
727727

728728
`template`允许接收的参数可以是类型信息或数据信息。
729729

730-
注意:模版参数必须都是在编译时确定的
730+
注意:模板参数必须都是在编译时确定的
731731

732732
#### `constexpr`的使用
733733

734-
### 函数模版的使用
734+
### 函数模板的实例化与特化
735735

736736
#### 实例化
737737

738738
显式实例化和隐式实例化。
739739

740-
#### 函数模版的重载
740+
#### 函数模板的重载
741741

742742
`swap`函数为例,我们可以用它来交换两个`T[]`数组的内容。这是一种重载。
743743

744744
#### 特化
745745

746-
特化模版函数,用于特殊的类型。
746+
特化模板函数,用于特殊的类型。
747747

748748
#### 编程示例:`swap`对于字符串的特化
749749

750750
这里要交换的就是内容,而非指针。
751751

752-
### 类模版
752+
### 类模板
753753

754-
#### 什么是类模版
754+
#### 什么是类模板
755755

756-
我们可以忽略它的部分成员的具体类型,为具有相同特征的成员搭建一个通用的类模版
756+
我们可以忽略它的部分成员的具体类型,为具有相同特征的成员搭建一个通用的类模板
757757

758-
#### 编程示例:`array`类模版
758+
#### 编程示例:`array`类模板
759759

760-
一个非常简化的`array`类模版,只能实现最基础、最简单的功能,但足够用来讲解了。
760+
一个非常简化的`array`类模板,只能实现最基础、最简单的功能,但足够用来讲解了。
761761

762-
#### 如何使用类模版
762+
#### 如何使用类模板
763763

764-
与函数模版相似,类模版的参数也是要在编译时确定的
764+
与函数模板相似,类模板的参数也是要在编译时确定的
765765

766-
### 类模版的使用
766+
### 类模板的实例化与特化
767767

768768
#### 实例化
769769

770770
显式实例化和隐式实例化。
771771

772-
与函数模版相似,类模版也不是一个预先给定的类。编译器根据需要,会根据类模版生成若干个对应的类定义
772+
与函数模板相似,类模板也不是一个预先给定的类。编译器根据需要,会根据类模板生成若干个对应的类定义
773773

774774
#### 完全特化
775775

@@ -779,7 +779,7 @@
779779
780780
### 编程示例:智能指针
781781

782-
带读者写一个`auto_ptr`类模版
782+
带读者写一个`auto_ptr`类模板
783783

784784
> 虽然`auto_ptr`在C++17中已经被移除了,但是我们泛讲篇不需要考虑得太细,能写出来一个简单的`auto_ptr`对初学者来说就已经是不小的成就了。
785785
@@ -813,7 +813,7 @@
813813

814814
### 编程示例:`at`成员函数
815815

816-
`array`类模版设计一个成员函数`at`,带范围检测,继承自`std::exception`
816+
`array`类模板设计一个成员函数`at`,带范围检测,继承自`std::exception`
817817

818818
### `noexcept`限定
819819

@@ -963,15 +963,15 @@ Placement new。主要是介绍下布置分配的语法和注意事项(结束
963963

964964
## 函数与闭包
965965

966-
### 函数模版相关
966+
### 函数模板相关
967967

968968
#### 实例化与参数推导
969969

970970
编译器将如何根据代码中给定实参的类型,推导出函数的类型。
971971

972-
#### 函数模版的重载
972+
#### 函数模板的重载
973973

974-
如何重载模版参数,来实现我们的特定目的。
974+
如何重载模板参数,来实现我们的特定目的。
975975

976976
#### 显式特化与直接重载
977977

@@ -1039,11 +1039,11 @@ Placement new。主要是介绍下布置分配的语法和注意事项(结束
10391039

10401040
#### 友元
10411041

1042-
类中的友元函数和友元函数模版
1042+
类中的友元函数和友元函数模板
10431043

1044-
类中的友元类和友元类模版
1044+
类中的友元类和友元类模板
10451045

1046-
类模版的友元函数
1046+
类模板的友元函数
10471047

10481048
### 构造与使用
10491049

@@ -1057,13 +1057,13 @@ Placement new。主要是介绍下布置分配的语法和注意事项(结束
10571057

10581058
####
10591059

1060-
### 类模版相关
1060+
### 类模板相关
10611061

10621062
#### 实例化与参数推导
10631063

10641064
同上的部分同上。
10651065

1066-
#### 类模版模版的重载
1066+
#### 类模板模板的重载
10671067

10681068
同上的部分同上。
10691069

@@ -1073,7 +1073,7 @@ Placement new。主要是介绍下布置分配的语法和注意事项(结束
10731073

10741074
#### 显式部分特化
10751075

1076-
在这里要着重讲一下显式部分特化,这是相比于函数模版不同的地方
1076+
在这里要着重讲一下显式部分特化,这是相比于函数模板不同的地方
10771077

10781078
### (待补充)
10791079

@@ -1083,7 +1083,7 @@ Placement new。主要是介绍下布置分配的语法和注意事项(结束
10831083

10841084
阐释,为什么虚继承是一个关系。
10851085

1086-
## 标准模版库
1086+
## 标准模板库
10871087

10881088
### 基本概念
10891089

@@ -1123,9 +1123,9 @@ Placement new。主要是介绍下布置分配的语法和注意事项(结束
11231123

11241124
#### `output_iterator`
11251125

1126-
### 实操:简易的`vector`类模版设计
1126+
### 实操:简易的`vector`类模板设计
11271127

1128-
### 实操:简易的`list`类模版设计
1128+
### 实操:简易的`list`类模板设计
11291129

11301130
### 实操:简易的算法设计
11311131

code_in_book/11.1/swap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ void swap(T &a, T &b) {
99
a = b;
1010
b = tmp;
1111
}
12-
template<typename T, std::size_t N> //模版参数N表示这个数组的长度
12+
template<typename T, std::size_t N> //模板参数N表示这个数组的长度
1313
void swap(T (&a)[N], T (&b)[N]) { //参数是两个T(&)[N]
1414
for (int i = 0; i < N; i++)
1515
user::swap(a[i], b[i]); //调用已经定义好的user::swap

code_in_book/11.2-11.3/is_same.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#pragma once
2+
#include <type_traits> //std::is_same定义在type_traits库中
3+
namespace user { //定义在user命名空间中
4+
template<typename T1, typename T2>
5+
constexpr bool is_same() { //比较两个类是否相同,最好加上constexpr
6+
return std::is_same<T1, T2>::value; //调用std::is_same,代码重用
7+
}
8+
template<typename T1, typename T2>
9+
constexpr bool is_same(const T2 &obj) { //比较对象obj是不是T1类型
10+
return std::is_same<T1, T2>::value; //可以直接比较T1和T2
11+
}
12+
template<typename T1, typename T2>
13+
constexpr bool is_same(const T1 &obj1, const T2 &obj2){ //比较两个对象是否同类
14+
return std::is_same<T1, T2>::value; //同上
15+
}
16+
};

code_in_book/11.2-11.3/main.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "Header.h"
2+
#include <iostream>
3+
int main() {
4+
int (*p1)[3] {}, *p2[3] {};
5+
std::cout << user::is_same<int(*)[3], int*[3]>() << std::endl //输出0
6+
<< user::is_same<int(&)[3]>(*p1) << std::endl //输出0
7+
<< user::is_same<int*>(*p1) << std::endl //输出1
8+
//提示:函数参数传递过程中发生了int[3]到int*的隐式类型转换
9+
<< user::is_same<>(p1, p2) << std::endl; //输出0
10+
return 0;
11+
}

code_in_book/5.1/输入数据求最大值.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ using namespace std;
55
void input_clear(istream& = {cin}); //在声明中就给出默认参数,注意类型是引用
66
template<typename T>
77
T maximum(T[], int); //T[]写成T*也没问题,不过习惯上还是写成数组形式
8-
template<typename T> //注意:每次声明(定义)模版时必须写一个template
8+
template<typename T> //注意:每次声明(定义)模板时必须写一个template
99
unsigned input_arr(T[], const unsigned);
1010
//定义部分
1111
int main() { //主函数

generalized_parts/01_welcome_to_cpp.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
\chapter{初识C++}
22
在本章,我们将会了解一些C++中最基本的知识,最常见的概念,和最简单的语法,并付诸代码来实现。\par
3-
我们不要求读者搞懂每句代码的含义——那是不必要的。我们在本章中会给出一个基本的代码模版,读者只需修改其中的一小部分即可。毕竟,\textbf{学习都是从模仿开始的},C++也不例外。\par
3+
我们不要求读者搞懂每句代码的含义——那是不必要的。我们在本章中会给出一个基本的代码模板,读者只需修改其中的一小部分即可。毕竟,\textbf{学习都是从模仿开始的},C++也不例外。\par
44
有一点值得注意。我们需要有一个编译器,来把我们的代码(.cpp文件或者别的什么)变成可以执行和看到效果的程序(Windows中的.exe文件、Linux或MacOS上的可执行文件,或者别的什么),以便检查它能否实现我们想要的功能,并在日后使用这个程序。\par
55
根据自己计算机的系统,你可以选择\href{https://www.embarcadero.com/free-tools/dev-cpp}{Embarcadero Dev-C++ (Windows)}, \href{https://learn.microsoft.com/zh-cn/cpp/?view=msvc-170}{Microsoft Visual C++ (Windows)}, \href{https://developer.apple.com/xcode/}{Apple Xcode (MacOS)}, \href{https://github.com/open-watcom/open-watcom-v2}{Open Watcom C++ (Windows/Linux/DOS)}, \href{https://www.codeblocks.org/}{Code::Blocks (跨系统)}, \href{https://www.monodevelop.com/}{MonoDevelop (跨系统)}。这些都是集成开发环境\footnote{集成开发环境(Integrated Development Environment, IDE),是一种辅助进行软件开发的应用。在开发工具内部就可以编写源代码,并编译打包成为可用的程序。IDE需要的配置较少,对新手比较友好,上手容易。},你只需要在下载后做很简单的配置,就可以开始写代码了。\par
66
另外还有一些代码编辑器,比如\href{https://code.visualstudio.com/}{Visual Studio Code (Windows/Linux/MacOS)}, \href{https://www.sublimetext.com/}{Sublime Text (Windows/Linux/MacOS)}, \href{https://www.vim.org/}{Vim (跨系统)},你需要做额外的配置(比如安装插件),把它们变得如同集成开发环境一样。\par

generalized_parts/01_welcome_to_cpp/06_classes_and_objects.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ \section{类与对象}
55
\item \textbf{C}:这是脱胎于C语言的部分,它继承和发展了C语言中的部分功能。所以当有人问起``如果没学过C语言,是不是要先学C再学C++''的时候,我们的回答都是``不必如此''!在C++的起步阶段中你学习的内容已经基本涵盖C语言了。
66
\item \textbf{面向对象的C}:这里有了比C语言中 \lstinline@struct@ 丰富得多的功能,它也是C with Classes最初区别于C的特征。
77
\item \textbf{泛型C}:这里提供了泛型编程和元编程的支持,使C++成为一门更为强大的语言。它们是C++与C with Classes的重要区别之一。
8-
\item \textbf{标准模版库(STL)}:STL由斯捷潘诺夫\footnote{亚历山大·亚历山德罗维奇·斯捷潘诺夫(Alexander Alexandrovich Stepanov),俄罗斯裔美国计算机科学家,以其提倡泛型编程与设计实现了C++语言中的标准模版库而闻名。}设计实现。相比于单纯的泛型编程,它有一套相对独立的逻辑。STL更多地支持对``现成''数据结构和算法的使用,其优点是方便、高效、简洁。
8+
\item \textbf{标准模板库(STL)}:STL由斯捷潘诺夫\footnote{亚历山大·亚历山德罗维奇·斯捷潘诺夫(Alexander Alexandrovich Stepanov),俄罗斯裔美国计算机科学家,以其提倡泛型编程与设计实现了C++语言中的标准模板库而闻名。}设计实现。相比于单纯的泛型编程,它有一套相对独立的逻辑。STL更多地支持对``现成''数据结构和算法的使用,其优点是方便、高效、简洁。
99
\end{itemize}
1010
这些内容都会在本书的泛讲篇或精讲篇有所涉及。但本书并非进阶教程,读者若有意深入挖掘,还应选择合适的进阶教材阅读。\par
1111
从C++的发展史来看,\textbf{面向对象编程(Object-oriented programming, OOP)}是C++相对于C跨出的第一步。面向对象的概念广泛用于C++的语法中,以至于我们往往日用而不知。\par

generalized_parts/02_basic_operation_on_data/02_fundamental_types.tex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ \subsection*{整型}
1616
4294967295
1717
}\\\noindent\rule{\textwidth}{.2pt}\par
1818
这里需要介绍几点:\par
19-
首先,\lstinline@numeric_limits@ 是一个类模版\footnote{关于类模版的有关知识,我们将在第十一章中讲解。},它要接收一个``''作为模版参数。比如说,在这个例子中,我们分别使用了 \lstinline@short@ 和 \lstinline@unsigned@ 作为模版参数,然后用 \lstinline@lowest()@ 和 \lstinline@max()@ 成员函数\footnote{关于函数的基本知识,我们将在第四章中讲解;而关于类的成员函数,我们将在第八章讲解。}来求出我们想要知道的值。如果你愿意,也可以把这段代码中的类型改成其它任何一个基本数据类型,然后观察输出,比如 \lstinline@double@ 或 \lstinline@char@。\par
19+
首先,\lstinline@numeric_limits@ 是一个类模板\footnote{关于类模板的有关知识,我们将在第十一章中讲解。},它要接收一个``''作为模板参数。比如说,在这个例子中,我们分别使用了 \lstinline@short@ 和 \lstinline@unsigned@ 作为模板参数,然后用 \lstinline@lowest()@ 和 \lstinline@max()@ 成员函数\footnote{关于函数的基本知识,我们将在第四章中讲解;而关于类的成员函数,我们将在第八章讲解。}来求出我们想要知道的值。如果你愿意,也可以把这段代码中的类型改成其它任何一个基本数据类型,然后观察输出,比如 \lstinline@double@ 或 \lstinline@char@。\par
2020
其次是``输出换行''的问题。当我们的代码中有多个输出语句的时候,程序会在运行时按顺序执行这些输出语句。但是程序不会自己添加分隔符\footnote{分隔符(Delimiter),指的是将一系列内容按同样的格式分开的符号,它有点像标点符号,但又不尽然。分隔符既方便人类阅读,又让计算机能够分辨不同的数据。比如说,我们用空格将一系列词语分开,这时空格就是它们的分隔符。},它会这样输出(以刚才程序为例):\\\noindent\rule{\textwidth}{.2pt}\texttt{
2121
-327683276704294967295
2222
}\\\noindent\rule{\textwidth}{.2pt}\\
@@ -105,7 +105,7 @@ \subsubsection*{字符串简介}
105105
\subsection*{布尔型}
106106
布尔型是一种特殊的整型,它一般用来表示一种逻辑判断的信息。举例来说,``\lstinline@2>3@''是一个逻辑判断,它的值为``''(False);而``\lstinline@"Hello World!"@ 的内存占用为13字节''也是一个逻辑判断,它的值为``''(True)。\par
107107
布尔型数据用关键字 \lstinline@bool@ 来定义,它只有两个可能的取值:\lstinline@true@ 和 \lstinline@false@。在编码时,它们分别被编为 \lstinline@1@ 和 \lstinline@0@。\par
108-
按理说,我们只需要一个比特就能表示一个布尔变量。然而,内存当中的比特并不是独立的寻址单元,所以一个布尔型变量必须要用一整个字节来存储。\footnote{标准模版库中的 \lstinline@vector<bool>@ 采用了优化方法,使得每个字节可以存储8个布尔数据,这就提升了存储空间的利用率。}读者可以用 \lstinline@sizeof@ 来验证它。\par
108+
按理说,我们只需要一个比特就能表示一个布尔变量。然而,内存当中的比特并不是独立的寻址单元,所以一个布尔型变量必须要用一整个字节来存储。\footnote{标准模板库中的 \lstinline@vector<bool>@ 采用了优化方法,使得每个字节可以存储8个布尔数据,这就提升了存储空间的利用率。}读者可以用 \lstinline@sizeof@ 来验证它。\par
109109
布尔型数据在输出时默认以整型数据的格式输出,于是 \lstinline@false@ 会被输出为 \lstinline@0@,而 \lstinline@true@ 会被输出为 \lstinline@1@。
110110
\begin{lstlisting}
111111
bool judgement {2>3}; //定义bool型变量judgement,其值为false

0 commit comments

Comments
 (0)