注意:代码环境为 VS2022
# C++ 介绍
C++(C Plus Plus),是由微软 (Microsoft) 公司基于 C 语言扩充编写的一门语言。
C++ 是一门面向对象的语言
其中部分语法与 C 语言相似,可以参考 C 语言笔记 (有些部分我直接从 C 语言笔记里复制过来了,我会将其标出)。
# Hello World
1 2 3 4 5 6 #include <iostream> using namespace std;int main () { cout << "Hello World!" << endl; return 0 ; }
请自行安装 VS2022 (或者其他 ide),可以参考 C 语言笔记的内容。
输入上面的代码,实现第一个 C++ 程序
# C++ 语法
# 注释
# 位 (bit) 与字节 (byte)
在日常使用计算机的时候,我们通常会看到一些数据单位,如 kb,MB,GB 等
其中 kb 指的是 kilo byte (千字节),mb 指的是 mega byte (兆字节)。诸如此类的还有 TB,PB,EB 等。
计算机是电子产品,对其来说,只存在开路 (0) 与闭路 (1)
我们将一个最基础的单位 (0 或 1) 称为位 (bit),将 8 个位合在一起称为一个字节 (byte)。
当我需要将整数 8 存入计算机时,8 会被转换为二进制数 1000 被存入到内存中。
这在 C 语言中,通常会占用 4 个字节,也就是 32 位。
# 数据类型
# 基本数据类型:
基本数据类型包括:
数值类型:
字符类型 (char)
其中整型包括:短整型 (short)、整型 (int)、长整型 (long)
其中浮点型包括:单精度型 (float)、双精度型 (double)
整型,即为整数。 浮点型,即为小数。
短整型、整型与长整型的差距在于其存储时,占用的字节数
类型
字节数
存储数值的范围
short
2
-2^15, 2^15-1
int
4
-2^31, 2^31-1
long
8
-2^63, 2^63-1
这是大致的内存占用情况,需要注意的是,这些数据类型在不同的系统上,会占用不同的字节数,而非固定。
通过类型占用的字节数,可以计算出其存储数值范围。
例如:int 是 4 个字节,也就是 32 位,因为其存储的是二进制数,所以理论上范围应该是 [-2^32,2^32 - 1] 但第一位要用于存储其符号,也就是数值是正还是负,所以占用了一个位,则其范围变为 [-2^31,2^31 - 1],正数范围需要减一是为了存储 0
单精度浮点型与双精度浮点型的区别:
类型
字节
存储数值的范围
float
4
-3.4*10^38, 3.4*10^38
double
8
-1.7*10^308, 1.7*10^308
其中单精度浮点数可以存储到小数点后 6 位数字,而双精度浮点数可以存储到小数点后 15 位数字。
打印时,默认保留 6 位小数
# 布尔类型
需要注意,C 语言并没有布尔类型,但是程序中经常会用到布尔类型,因此我在这里单独拿出来使用
在 C89 标准时,C 语言没有布尔类型,在后来的 C99 标准时,才引入了布尔类型。
布尔类型是只有两种值的数据类型,包含真 (True) 与假 (False)
在 C 语言中,通常使用 0 作为布尔类型的 False,非 0 作为布尔类型的 True
# 构造类型
构造类型包括:
数组 (array)
结构体 (struct)
共用体 (union)
枚举类型 (enum)
这四种类型会在后面讲到。
# 指针类型
指针类型通常占用 4 个字节,存储十六进制数,用于保存地址值,具体会在指针的部分讲到。
# 空类型
型如其名,空 (void)
# 变量
这块儿从 C 语言笔记那里复制过来的所以用的输出方式可能是 printf 而不是 cout
# 声明变量与赋值:
创建一个新的源文件,并将先前的第一个程序全部注释掉:
1 2 3 4 5 6 7 8 9 10 #include <stdio.h> int main () { int var1; var1 = 0 ; float var2 = 0.123f ; double var3 = 0.123456 ; char var4 = 'c' ; printf ("%d,%f,%lf,%c" , var1, var2, var3, var4); return 0 ; }
声明变量,即创建一个变量,然后使用 = 为其赋值。
注意:赋值行为是将等号右边的数值分配给等号左边的变量,不能写反!
第一次给变量赋值的行为,被叫做初始化 ,声明与初始化可以写在同一行,如 var2 与 var3
注意 2:请不要在未初始化的情况下调用变量,会导致程序错误!
IDE 会默认浮点数为双精度浮点数,在浮点数后面添加 f (或 F),标志其为单精度浮点数 (也可以不加)。
打印时,使用占位符进行占位,占位符与后面的变量需要一一对应。其中 % d 为整型的占位符,% f 为单精度浮点型的占位符,% lf 为双精度浮点型的占位符。
# 变量名:
变量命名时需要遵循一定的规则:
变量名只能包含字母、数字、下划线和 $
变量名只能以字母、下划线或者 $ 开头
变量名不能使用关键字
变量名严格区分大小写
1 2 3 4 5 6 7 8 9 int 123 abc;int int ;int 变量;int var;int _var;int $var;int VAR;
关键字:C 语言使用到的单词,例如:int,float,void 等,在起变量名或者函数名时需要避开。
关键字并不需要记忆,在 VS2022 中,当使用到关键字时,会被特殊的颜色标出。
除了必要的语法外,我们在日常编程中也有一些默认规则。
变量名要做到见名知意
变量名遵循驼峰法,或者下划线法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int var;int count;int sum;int studentId;char studentAddress;int student_name;int student_class;
驼峰法与下划线法的选择看个人喜好。
# 运算符
需要注意,运算符区分优先级,大致为:
数值运算符 > 比较运算符 > 逻辑运算符 (不绝对)
其中逻辑运算符中!> && > ||
具体优先级可以自行搜索
# 数值运算符
C 语言中提供一些数值运算的符号,如下:
符号
作用
使用方法
=
赋值运算符,将等号右侧的值赋给等号左边的变量
var = 10
+
加运算符
var = 1 + 2
-
减运算符
var = 2 - 1
*
乘运算符
var = 5 * 10
/
除运算符
var = 10 / 5
%
求余数运算符
var = 11 % 5 (var 的值为 1)
+=
可以将右侧式子理解为 var = var + 10
var += 10
-=
可以将右侧式子理解为 var = var - 10
var -= 10
*=
可以将右侧式子理解为 var = var * 10
var *= 10
/=
可以将右侧式子理解为 var = var / 10
var /= 10
%=
可以将右侧式子理解为 var = var % 10
var %= 10
++
自增运算,相当于 var = var + 1
var++(或者 ++var)
–
自减运算,相当于 var = var - 1
var–(或者–var)
注意:var++ 与 ++var 使用方式并不相同,var-- 与 --var 同样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <stdio.h> int main () { int var = 1 ; var += 10 ; printf ("%d\n" , var); var -= 10 ; printf ("%d\n" , var); var *= 10 ; printf ("%d\n" , var); var /= 10 ; printf ("%d\n" , var); var = 11 ; var %= 10 ; printf ("%d\n" , var); printf ("%d\n" , var++); printf ("%d\n" , ++var); return 0 ; }
运行上述代码,可以发现打印结果为:
需要注意的是后 ++ 与前 ++ 的区分:
使用后 ++ 时,是首先使用变量 var,再进行自增,所以当 var=1 时,使用 var++ 进行打印,首先使用 var 打印出 1,然后对其进行自增,则 var=2.
使用前 ++ 时,是首先自增,再使用变量 var,所以当 var=2 时,使用 ++var 进行打印,首先自增,使 var 变为 3,然后对 var 进行打印,打印出数字 3.
# 比较运算符
C 语言中提供一些比较运算的符号,如下:
符号
作用
使用方法
<
判断左值是否小于右值,返回布尔类型
number1 < number2
>
判断左值是否大于右值,返回布尔类型
number1 > number2
<=
判断左值是否小于或等于右值,返回布尔类型
number1 <= number2
>=
判断左值是否大于或等于右值,返回布尔类型
number1 >= number2
==
判断左值是否等于右值,返回布尔类型
number1 == number2
!=
判断左值是否不等于右值,返回布尔类型
number1 != number2
注意:C 语言自带的数据类型中,并没有真正的布尔类型,只是使用零和非零模拟出的布尔类型
# 逻辑运算符
C 语言中提供一些逻辑运算的符号,如下:
符号
作用
使用
&&
逻辑与,判断左值与右值是否都为真,返回布尔类型
a && b
||
逻辑或,判断左值或右值是否为真,返回布尔类型
a || b
!
逻辑非,取其相反值,返回布尔类型 (若 a 为 True,则!a 为 False)
!a
逻辑与,逻辑或,逻辑非的运算结果如下:
&& 运算
b = True
b = False
a = True
True
False
a = False
False
False
逻辑与:全真才真,一假皆假。
|| 运算
b = True
b = False
a = True
True
True
a = False
True
False
逻辑或:一真即真,全假才假。
短路现象:
对于 a&&b,当 a 为假的时候,我们便可以立即断定 a&&b 就是假的,那么程序将不会再判断 b,这种现象被称为短路现象。
同样的,对于 a||b,当 a 为真,则 a||b 就一定是真的,程序也不会再判断 b。
# 位运算符
C 语言中提供一些位运算的符号,如下:
符号
作用
使用
&
对左值与右值进行与运算
a & b
|
对左值与右值进行或运算
a | b
^
对左值与右值进行位运算
a ^ b
<<
对左值进行左移运算,左移位数取决于右值
1 << 5
>>
对左值进行右移运算,右移位数取决于右值
32 >> 3
使用如下代码进行测试:
1 2 3 4 5 6 7 8 9 10 #include <stdio.h> int main () { int a = 1 , b = 5 ; printf ("%d\n" , a & b); printf ("%d\n" , a | b); printf ("%d\n" , a ^ b); printf ("%d\n" , 1 << 5 ); printf ("%d\n" , 32 >> 3 ); return 0 ;c }
会发现,最终输出的结果分别是 1,5,4,32 和 4 接下来我会对位运算做详细解释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
# 数据类型转换
将低精度值赋值给高精度值时,数据会自动转换类型,示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <stdio.h> int main () { char c = 'a' ; int number1 = 10 ; float number2 = 10.10 ; double number3 = 100.100 ; number1 = number2; number1 = (int )number2; number2 = number1; number3 = number2 = number1 = c; printf ("%lf" , number3); return 0 ; }
需要注意的是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <stdio.h> int main () { int var1 = 1.1 ; int var2 = 1.6 ; float var3 = 3 / 5 ; printf ("%d,%d,%f" , var1, var2, var3); return 0 ; }
得到结果为 1,1,0.000000
其中 var1 与 var2 已经解释过了,而其中为 float 类型的 var3 结果却是 0.000000
这是因为参与计算的数值均为整型,即 3 / 5,运算出来的返回结果也只能是整型,得到的结果是被截断过后的整型 0,最后打印出的结果是 0.000000
若要返回结果为浮点型,则需要使用浮点型数值参与运算,比如改为
# 分支语句语句
# if、else if、else 语句
在生活中,我们经常会遇到分支情况,例如:
如果沙县小吃比大盘鸡更便宜,我今天就去吃沙县小吃,否则的话就去吃大盘鸡。
我们注意到,在这句话里出现了两条分支:
去吃沙县小吃
去吃大盘鸡
而我们根据:哪个更便宜?这个条件对我们要做的选择进行判断。
在编程中,我们也可以实现类似的分支情况,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> using namespace std;int main () { int sha_xian = 20 , da_pan_ji = 58 ; if (sha_xian < da_pan_ji) { cout << "今晚吃沙县" << endl; } else { cout << "今晚吃大盘鸡" << endl; } return 0 ; }
这部分代码,相信许多人只是读一遍,便能够理解,接下来我要详细介绍 if 语句的细节,首先是语法:
这是一个 if 语句的语法,如果 if 后的代码块仅仅只有 1 句 (1 个分号为 1 句),那么可以不写大括号,如下:
1 2 if (布尔类型) cout << "只有一句代码时,可以不写大括号" << endl ;
当括号内的布尔类型为真时,执行这条 if 语句,为假时,则不会执行。
可以使用上面提到的比较运算符来获得布尔类型,如上面的沙县、大盘鸡比较代码。
需要注意的是,if 语句可以单独使用,而 else 语句不可以,else 语句必须要有对应的 if 语句。
1 2 3 4 5 6 if (布尔类型){需要执行的代码块}else {需要执行的代码块}else {代码块}
当 if 内的布尔类型为假时,程序便会不执行 if 语句,直接进入 else 语句
如果 else 后面的语句仅仅只有 1 句,也可以不写大括号
else 语句的匹配规则遵循就近原则:
1 2 3 if (布尔类型) {代码块}if (布尔类型) {代码块}else {代码块}
回到上面的沙县与大盘鸡案例,我们可以想到,其价格的比较结果并非一定只有两种,还会有相同的情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> using namespace std;int main () { int sha_xian = 20 , da_pan_ji = 58 ; if (sha_xian < da_pan_ji) { cout << "今晚吃沙县" << endl; } else if (sha_xian == da_pan_ji) { cout << "吃哪个都可以" << endl; } else { cout << "今晚吃大盘鸡" << endl; } return 0 ; }
可以在 if 的下面添加 else if 语句来判断这种情况,else if 语句的作用类似于 if 语句,但是不能单独使用
else if 可以存在不止一句
同样的,当 else if 语句后面只有一条语句时,可以不写大括号。
# switch 语句
在生活中,除了如同 if、else 这种分支,还存在多分支的情况,例如:
如果今天是周一,我就去学 C 语言
如果今天是周二,我就去学 C++
如果今天是周三,我就去学 Java
如果今天是周四,我就去学 Python
如果今天是周五,我就去学 C#
如果今天是周六,我就出去玩
如果今天是周日,我就睡懒觉
当然,这种多分支的情况可以使用多个 else if 去实现,但是当分支过多,if 语句的效率通常不如 switch 语句。
首先介绍一下 switch 语句的语法:
1 2 3 4 5 6 7 8 9 10 11 12 13 switch (变量){case 值1 : 执行代码块; break ; case 值2 : 执行代码块; break ; case 值3 : 执行代码块; break ; default : 执行代码块; }
switch 后面的括号中的变量可以是整型或者字符型。
当变量的值等于值 1 时,便会执行 case 值 1: 后面的代码块。
需要注意的时,case 语句后面的是冒号而不是分号。
当 case 语句后的代码块被执行完后,如果有 break 语句,则会终止 switch,如果没有 break 语句,则会继续向下执行。
例如:
1 2 3 4 5 6 7 8 switch (key){case 1 : printf ("1" ); case 2 : printf ("2" ); case 3 : printf ("3" ); }
对于上面的这个 switch 语句来说,如果 key 的值为 1,则最后的打印结果会是 123
如果 key 的值为 2,则最后的打印结果会是 23,这种现象被称为穿透效果
default 语句并非必要,可以不写
default 语句类似于 if 语句中的 else,当所有情况都不被匹配到时,会被执行。
如果 default 上面的语句并没有写 break;那么 default 也会被穿透。
接着我们回到上面的问题,如果使用 switch 语句实现,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> using namespace std;int main () { int date = 1 ; switch (date) { case 1 : printf ("今天是周一,我去学C语言" ); break ; case 2 : printf ("今天是周二,我去学C++" ); break ; case 3 : printf ("今天是周三,我去学Java" ); break ; case 4 : printf ("今天是周四,我去学Python" ); break ; case 5 : printf ("今天是周五,我去学C#" ); break ; case 6 : printf ("今天是周六,我出去玩" ); break ; case 7 : printf ("今天是周日,我睡懒觉" ); break ; default : printf ("今天周几都不是,什么都不干" ); } return 0 ; }
我们通过另一个案例来感受一下穿透效果:
小明的爸爸许诺给小明:
如果小明的期末成绩高于 60 分,便给他 100 元钱
如果高于 80 分,便给他买手机、和给他 100 元钱
如果高于 100 分,便给他买电脑、手机,而且给他 100 元钱
使用 switch 实现的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <stdio.h> int main () { int score = 100 ; switch (score / 10 ) { case 10 : printf ("给小明买电脑\n" ); case 9 : case 8 : printf ("给小明买手机\n" ); case 7 : case 6 : printf ("给小明100元钱\n" ); } return 0 ; }
通过这个代码,我们很轻松的实现了小明爸爸的许诺这个案例。
# 指针 (从 C 中复制)
# 初识
指针是 C 语言中一个十分重要的概念。
指针的长度为 4 个字节,内部存储的是一个十六进制数。
在数据类型的后面添加一个星号,以创建对应的类型指针,如下:
1 2 int * int_pointer;float * float_pointer;
指针存储的十六进制数,是内存中对应的位置,也被称为地址
我们在 scanf 中见到过 & 符号,这个符号用于取出一个变量的地址,如下:
1 2 int number = 0 ;int * int_pointer = &number;
地址是一个十分形象的名字,正如我们每个人都有自己的家庭地址,地址记录了一个变量在内存中存储的位置。
指针的初始化通常使用 NULL 来进行:
1 int * int_pointer = NULL ;
当你创建了一个指针,但暂时不知道需要让它指向谁时,可以赋给其 NULL (空指针) 来避免错误调用未初始化的指针。
可以通过解引用符号 (星号),来调用一个指针所指向的地址中保存的值,如下:
1 2 3 4 5 int number = 0 ;int * int_pointer = &number;printf ("%d\n" , *int_pointer);printf ("%p\n" , int_pointer);
指针也可以做基本的运算,例如使用指针做自增运算:
1 2 3 int number = 0 ;int * int_pointer = &number;int_pointer++;
指针自增时,会根据其类型增加相应的字节数,比如整型指针,实际是自增了一个 int (4 个字节) 的大小。
这种使用方式通常配合内存管理 (malloc、free) 或者数组使用,在后面会详细介绍
注意!这里仅做一个示范,实际上这样使用是错误的,会导致指针指向未知的内存空间。
# 值传递与指针传递
根据已经学习过的知识,我们可以简单的写出一个交换 a,b 变量值的程序:
1 2 3 4 5 6 7 8 9 #include <stdio.h> int main () { int a = 10 , b = 20 ; int temp = a; a = b; b = temp; printf ("%d,%d" , a, b); return 0 ; }
然后将其封装成一个函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> void Swap (int x, int y) ;int main () { int a = 10 , b = 20 ; Swap(a, b); printf ("%d,%d" , a, b); return 0 ; } void Swap (int x, int y) { int temp = x; x = y; y = temp; }
通过打印,我们可以发现,a 与 b 的值并未实现交换。
这与值传递、地址传递有关。
对于一个函数的形参 (形式参数,即上面函数中的 x 和 y),在调用函数时,会自动生成新的变量 x, y 然后把 a 和 b 的值赋给对应的形参。
这样我们就不难理解为什么 Swap 函数并未改变 a 与 b 的值,因为函数从始至终都未与变量 a、b 打过交道
那么如果我想要使用函数修改一个变量的值,该怎么做?那就是传递一个变量的地址,修改成如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> void Swap (int * x, int * y) ;int main () { int a = 10 , b = 20 ; Swap(&a, &b); printf ("%d,%d" , a, b); return 0 ; } void Swap (int * x, int * y) { int temp = *x; *x = *y; *y = temp; }
因为每个变量对应的地址是唯一的,所以使用指针通过地址对值进行修改,就一定可以修改到目标变量。
另外,指针传递也可以减少值的复制,这一应用会在数组与结构体中体现。
# 函数指针与回调函数
函数指针是指向函数的指针变量。
通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。
函数指针可以像一般函数一样,用于调用函数、传递参数。
函数指针变量的声明:
1 2 3 4 5 6 7 8 9 10 11 12 13 函数返回值类型 (*函数指针名)(参数类型列表) = 函数名; #include <stdio.h> int max (int a, int b) { if (a > b) return a; return b; } int main () { int x = 10 , y = 20 ; int (*pointer_max)(int , int ) = max; printf ("max is %d" , pointer_max(x, y)); return 0 ; }
回调函数:当函数所需的参数列表中,包含函数指针时,该函数被称为回调函数。
即在函数中,通过函数指针调用另一个函数,示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> void print_Function () { cout << "printFunction被调用\n" << endl ; } void callback_Function (int times, void (*p_f_parameter)(void )) { for (int i = 0 ; i < times; i++) p_f_parameter(); } int main () { callbackFunction(10 , print_Function); return 0 ; }
其中 callback_Function 为回调函数。
# 多级指针
正如每个变量都有自己对应的地址,指针变量作为一个存储指针的变量,也有自己的地址。
我们可以使用一个二级指针来保存指针变量对应的地址,如下:
1 2 3 int number = 1 ;int * int_pointer = &number;int ** level_2_pointer = &int_pointer;
根据星号的数量可以判断一个指针的级别,以此类推,还有三级、四级、多级指针。
# 指针与常量
const 关键字与指针在一起使用时,有多种使用方法:
1 2 3 4 const int * p;int const * p;int *const p;
前两者的效果是相同的,常量指针正如同它的名字,这是指向常量的一个指针 。
对于常量指针来说,是不可以通过解引用符 (星号) 去改变其地址中保存的值的,因为地址中保存的值是一个常量,常量是不可修改的
1 2 3 4 5 const int *p;int a = 4 ;p = &a; *p = 5 ;
对于常量指针来说,指向的地址中存储的值不可修改,但指向的地址是可以修改的,如下:
而指针常量,指的是指针本身是一个常量 ,即指针指向的地址不可改变,但指向地址中存储的值可以改变,例如:
1 2 3 4 int a = 4 , b = 5 ;int *const p = &a;*p = 5 ; p = &b;
除此之外,还有指向常量的指针常量,即为以上二者的结合
const 修饰词可以在函数之间传递地址时,锁定数据,防止误操作
# 结构体 (从 C 中复制)
# 初识
C 中的类取代了结构体的作用,因此结构体在 C 中相对于 C 作用小很多。
定义结构体的语法:
1 2 3 4 5 6 7 struct struct_tag { member_element; member_element; member_element; ... }variable_struct;
一般情况下,结构体标签、成员元素、结构变量,这 3 部分至少要出现两个。如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <stdio.h> struct { int a; char b; float c; }my_struct; int main () { my_struct.a = 0 ; my_struct.b = '\0' ; my_struct.c = 0.0 ; return 0 ; }
或者这样定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <stdio.h> struct struct_tag { int a; char b; float c; }; int main () { struct struct_tag my_struct ; my_struct.a = 0 ; my_struct.b = '\0' ; my_struct.c = 0.0 ; return 0 ; }
另外结构体经常会配合 typedef 使用,使用方式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <stdio.h> typedef struct { int a; char b; float c; }struct_name; int main () { struct_name my_struct; my_struct.a = 0 ; my_struct.b = '\0' ; my_struct.c = 0.0 ; return 0 ; }
# typedef
使用 typedef 关键字可以自定义数据类型,如结构体:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <stdio.h> #include <string.h> typedef struct { int id; char name[10 ]; }Student; int main () { Student student; student.id = 123 ; strcpy (student.name, "张三" ); printf ("学生:%s, 学号:%d" , student.name, student.id); return 0 ; }
也可以用于给原有数据类型起别名:
1 2 3 4 5 6 typedef int ElementType;int main () { ElementType data = 123456 ; cout << data << endl ; return 0 ; }
# 堆区开辟数据 (new 关键字)
使用 new 关键字开辟堆区数据,使用 delete 关键字进行释放
注意:开辟的堆区需要程序员手动释放
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iostream> using namespace std;int main () { int * example = new int (10 ); cout << *example << endl; delete example; int * example = new int [10 ]; for (int i = 0 ;i < 10 ;i++) example[i] = i; for (int i = 0 ;i < 10 ;i++) cout << example[i] << endl; delete [] example; return 0 ; }
# 引用 (起别名)
# 使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include <iostream> using namespace std;int main () { int a = 10 ; int &b = a; int c = 20 ; swap (a,c); cout << "a=" << a << endl; cout << "c=" << c << endl; int &test01 = test (); cout << "test01=" << test01 << endl; test () = 1000 ; cout << "test01=" << test01 << endl; return 0 ; } void swap (int &a,int &b) { int temp = a; a = b; b = temp; } int & test () { static int number = 10 ; return number; }
# 本质
1 2 3 4 5 6 7 8 9 10 11 12 int a = 10 ;int &ref = a;ref = 20 ; void func (int & ref) { ref = 100 ; }
# 函数
函数基础参考 C 语言笔记
# 形参默认值与占位参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int example (int a,int b,int c = 20 ,int d = 30 ) { return a + b + c + d; } int main () { cout << example (10 ,10 ) << endl; return 0 ; } int func (int a,int ) { }
# 函数重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 void func () { cout << "func调用" << endl; } void func (int a) { cout << "func(int a)调用" << endl; } void func (double a) { cout << "func(double a)调用" << endl; } void func (int a,double b) { cout << "func(int a,double b)调用" << endl; } void func (double a,int b) { cout << "func(double a,int b)调用" << endl; } void func2 (int a,int b = 10 ) { cout << "func2(int a,int b = 10)" << endl; } void func2 (int a) { cout << "func2(int a)" << endl; }
# 类与对象
C++ 面向对象的三大特性:封装、继承、多态
C++ 认为万事万物皆对象,对象上有其属性和行为
# 封装
封装的意义:
1. 将属性和行为作为一个整体,表现生活中的事物
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 const double PI = 3.14 ;class Circle { public : int c_r; double calculateZC () { return 2 * PI * c_r; } } int main () { Circle c1; c1.c_r = 10 ; cout << "圆的周长为:" << c1.calculateZC () << endl; } class student {public : string s_name; int s_id; void showStudent () { cout << "姓名:" << s_name << "学号:" << s_id << endl; } void setName (string name) { s_name = name; } void setId (int id) { s_id = id; } }
2. 将属性和行为加以权限控制
struct 与 class 的区别:struct 的默认权限为 public,class 默认权限为 private
1 2 3 4 5 6 7 8 9 10 11 12 13 class C1 { int a; } struct C2 { int b; } int main () { C1 c1; C2 c2; c2.b = 100 ; }
# 构造函数与析构函数
构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动调用。
析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。
C++ 会自动提供构造函数 (空实现) 与析构函数 (空实现) 与拷贝构造函数。
当拥有构造函数 (有参) 时,C++ 将不再自动提供无参空实现,但仍提供拷贝构造函数。
当拥有拷贝构造函数时,C++ 不再自动提供其他构造函数。
构造函数语法:
1. 构造函数没有返回值,也不写 void。
2. 函数名与类名相同。
3. 构造函数可以有参数,因此可以发生重载。
4. 程序在调用对象时会自动调用构造函数,无需手动调用,而且只会调用一次。
== 析构函数语法:= =
1. 析构函数没有返回值,也不写 void。
2. 函数名与类名相同,函数名前要添加~
3. 析构函数不可以有参数,因此不能重载。
4. 程序在对象销毁前会自动调用析构函数,无需手动调用,而且只会调用一次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #pragma once #include <iostream> #include <string> using namespace std;class ClassLearn { public : ClassLearn (); ~ClassLearn (); int age; int * height; }; #include "ClassLearn.h" ClassLearn::ClassLearn () { age = 18 ; height = new int (175 ); cout << "构造函数" << endl; } ClassLearn::~ClassLearn () { if (height != NULL ){ delete height; height = NULL ; } cout << "析构函数" << endl; }
拷贝构造函数
1 2 3 4 5 6 7 8 9 10 class Person { private : int age; public : Person (const Person &p){ age = p.age; } }
# 深拷贝与浅拷贝
浅拷贝:
编译器提供的拷贝构造函数,仅进行浅拷贝操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Person () { public : int * age; Person (int age){ this ->age = new int (age); } ~Person (){ if (age != NULL ){ delete age; age = NULL ; } } } int main () { Person p1 (18 ) ; Person p2 (p1) ; return 0 ; }
当其中 p2 对 p1 进行拷贝时,p2 的 int* age 仅仅拷贝了 p1 中 age 的地址。
最后结束时,p2 (栈后进先出) 调用析构函数,释放了 age 指向的堆区内存。
p1 再调用析构函数,则会出现错误。
若要解决浅拷贝的不足,则需重写拷贝构造函数进行深拷贝:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 //例如 class Person(){ public: int* age; Person(int age){ this->age = new int(age); } Person(const Person &p){ this->age = new int(*p.age); } ~Person(){ if (age != NULL){ delete age; age = NULL; } } } int main(){ Person p1(18); Person p2(p1); return 0; }
# 初始化列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Phone { public : string m_pName; Phone (string pName):m_pName (pName){ } }; class Person { public : string name; int age; Phone phone; Person (string name,int age):age (age),name (name){ } };
# 静态成员
在成员变量或成员函数添加 static 关键字,称为静态成员
静态成员分为:
静态成员变量:1. 所有对象共享一份数据,2. 在编译阶段分配内存,3. 类内声明,类外初始化。
1 2 3 4 5 6 7 8 9 10 class Person { public : static int age; }; int Person::age = 18 ;int main () { cout << Person::age << endl; }
静态成员函数:1. 所有对象共享同一个函数,2. 静态成员函数只能访问静态成员变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Person { public : static int age; string name; static void func () { cout << "静态成员函数" << endl; name = "张三" ; } }; int Person::age = 18 ;int main () { Person::func (); }
# 成员变量与成员函数分开存储
1. 空对象占用 1 个字节。
2. 成员变量占用的空间,即为对象占用的空间。
3. 静态成员变量并不存储在对象上。
4. 成员函数并不存储在对象上。
# this 指针
this 指针无需定义,可直接使用。
this 指针是隐含每一个非静态成员函数内的一种指针。
this 指针指向 被调用的成员函数所属的对象。
用途:
当形参和成员变量同名时,可使用 this 区分。
在类的非静态成员函数中,返回对象本身,可以使用 return *this;
# const 修饰成员函数
成员函数后添加加 const 修饰,被称为常函数
常函数内不可以修改成员属性。
成员属性声明时使用 mutable 修饰,则可以在常函数中修改。
常对象:
声明对象前加 const 修饰,则称为常对象。
常对象只能调用常函数。
# 友元
作用:允许类外一些特殊的函数或类访问一些私有成员。
关键字:friend
1 2 3 4 5 6 7 8 9 10 11 12 13 class House { friend void goodGuy (House* house) ; friend class myFriend ; friend void myFriend::visit () ; private : string m_BedRoom; }; class myFriend {public : void visit () ; };
# 运算符重载
# 加号运算符重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> using namespace std;class Person {public : int age; Person (int age = 10 ):age (age){} Person operator + (Person& p) { Person temp; temp.age = this ->age + p.age; return temp; } }; int main () { Person p1 (18 ) ; Person p2 (20 ) ; Person p3 = p1 + p2; cout << p3.age << endl; return 0 ; } Person operator + (Person &p1, Person &p2){ Person temp; temp.age = p1.age + p2.age; return temp; }
# 左移运算符重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Person {public : string m_name; int m_age; Person (string name = "张三" , int age = 10 ) :m_name (name), m_age (age) {} }; ostream& operator <<(ostream& cout, Person& p) { cout << "m_name=" << p.m_name << "\n" << "m_age=" << p.m_age; return cout; } int main () { Person p1 ("张三" , 18 ) ; cout << p1 << endl; return 0 ; }
# 递增运算符重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <iostream> using namespace std;class MyInt {public : MyInt& operator ++() { num++; return *this ; } MyInt operator ++(int ) { MyInt temp (*this ) ; num++; return temp; } MyInt (int num = 10 ):num (num){} int num; }; ostream& operator <<(ostream& cout, MyInt myInt) { cout << myInt.num; return cout; } int main () { MyInt myInt (100 ) ; cout << (myInt++)++ << endl; cout << myInt << endl; return 0 ; }
# 赋值运算符重载
C++ 编译器提供的赋值运算,仅做浅拷贝。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Example { public : int * num; Example (int data){ num = new int (data); } ~Example (){ if (num != NULL ){ delete num; num = NULL ; } } }; int main () { Example e1 (18 ) ; Example e2 (20 ) ; e2 = e1; cout << *e1.num << endl; cout << *e2.num << endl; return 0 ; } Example& operator =(Example& e) { if (num != NULL ) { delete num; num = NULL ; } num = new int (*e.num); return *this ; }
# 关系运算符重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Person {public : string name; int age; Person (string name,int age):name (name),age (age){} bool operator ==(Person& p) { if (this ->name == p.name && this ->age == p.age) return true ; return false ; } bool operator !=(Person& p) { if (this ->name == p.name && this ->age == p.age) return false ; return true ; } }; int main () { Person p1 ("张三" , 18 ) ; Person p2 ("李四" , 18 ) ; if (p1 == p2) { cout << "p1与p2是相等的" << endl; } else cout << "p1与p2是不相等的" << endl; }
# 重载函数运算符
1 2 3 4 5 6 7 8 9 10 11 12 13 class MyAdd { public : int operator () (int a,int b) { return a + b; } }; int main () { MyAdd myAdd; cout << myAdd (10 , 8 ) << endl; return 0 ; }
# 继承
# 继承语法与权限
语法:
1 2 3 4 class FatherClass {};class ChildClass :public FatherClass{ };
继承可以用于减少重复代码,子类可以从父类那里继承相同的代码部分。
继承方式分为三种:
public:公共继承,无法访问 private,继承的成员权限与父类相同
protected:保护继承,无法访问 private,继承的的成员权限变为 protected。
private:私有继承,无法访问 private,继承的成员权限变为 private。
注:继承时仍然继承 private 成员,只是无法访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Enemy {public : int hp; int mp; }; class Solid :public Enemy {public : Solid (int hp, int mp) { this ->hp = hp; this ->mp = mp; } void SolidAttack () { cout << "This is SolidAttack" << endl; } }; class Boss :public Enemy {public : Boss (int hp, int mp){ this ->hp = hp; this ->mp = mp; } void BossAttack () { cout << "This is BossAttack" << endl; } }; int main () { Solid solid (100 , 100 ) ; Boss boss (1000 , 1000 ) ; solid.SolidAttack (); boss.BossAttack (); }
在实例化一个子类时,会先调用父类的构造函数,再调用子类的构造函数。
在销毁时,会先调用子类的析构函数,再调用父类的析构函数。
多继承:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class ChildClass :public Base1, public Base2{}; class Base { int data; }; class AClass :virtual public Base{};class BClass :virtual public Base{};class CClass :public AClass,public BClass{};
# 继承时子类与父类的同名成员
当子类中出现与父类中同名的成员时:
1 2 3 4 5 6 7 8 9 10 int main () { Son s; cout << "子类成员属性=" << s.element << endl; cout << "父类成员属性=" << s.Father::element << endl; cout << "子类成员函数" << s.func () << endl; cout << "父类成员函数" << s.Father::func () << endl; }
对于静态成员,同上。
# 多态
1. 多态分为两类:
静态多态:函数重载和运算符重载属于静态多态,复用函数名。
动态多态:派生类和虚函数实现运行时多态。
2. 静态多态和动态多态的区别:
静态多态的函数地址早绑定 - 编译阶段确定函数地址
动态多态的函数地址晚绑定 - 运行阶段确定函数地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Animal {public : virtual void speak () { cout << "动物在说话" << endl; } }; class Cat :public Animal {public : void speak () { cout << "小猫在说话" << endl; } }; void speak (Animal& animal) { animal.speak (); } int main () { Cat cat; speak (cat); }
多态满足条件:
多态使用条件:
重写:函数返回值类型、函数名、参数列表完全一致称为重写
# 纯虚函数与抽象类
纯虚函数:使用 virtual 关键字修饰,并且无实现的类成员函数。
语法:virtual void func () = 0;
抽象类:只要其中有一个纯虚函数,则这个类称为抽象类。
1. 抽象类无法实例化。
2. 抽象类的子类必须重写纯虚函数,否则该子类也为抽象类。
# 虚析构与纯虚析构
当使用父类指针指向子类,若子类中存有堆区数据,则结束时,仅调用父类的析构函数可能会无法释放子类的堆区数据,从而导致内存泄漏。
解决方法:将父类的析构函数改为虚析构函数。
纯虚析构:纯虚析构需要声明,也需要实现。
# 案例:Computer 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #pragma once #include <iostream> #include <string> using namespace std;class CPU {public : virtual void calculate () = 0 ; }; class Memory {public : virtual void storage () = 0 ; }; class GPU {public : virtual void display () = 0 ; }; class IntelCPU :public CPU {public : void calculate () ; }; class IntelGPU :public GPU {public : void display () ; }; class AMDCPU :public CPU {public : void calculate () ; }; class AMDGPU :public GPU {public : void display () ; }; class ZQMemory :public Memory {public : void storage () ; }; class MGMemory :public Memory {public : void storage () ; }; class Computer {public : Computer (CPU* cpu, Memory* memory, GPU* gpu); ~Computer (); void work () ; private : CPU* m_cpu; Memory* m_memory; GPU* m_gpu; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include "Computer.h" Computer::Computer (CPU* cpu, Memory* memory, GPU* gpu) { m_cpu = cpu; m_memory = memory; m_gpu = gpu; } Computer::~Computer () { if (m_cpu != NULL ) { delete m_cpu; m_cpu = NULL ; } if (m_memory != NULL ) { delete m_memory; m_memory = NULL ; } if (m_gpu != NULL ) { delete m_gpu; m_gpu = NULL ; } } void Computer::work () { m_cpu->calculate (); m_memory->storage (); m_gpu->display (); } void IntelCPU::calculate () { cout << "IntelCPU正在计算" << endl; } void IntelGPU::display () { cout << "IntelGPU正在显示" << endl; } void AMDCPU::calculate () { cout << "AMDCPU正在计算" << endl; } void AMDGPU::display () { cout << "AMDGPU正在显示" << endl; } void ZQMemory::storage () { cout << "芝奇内存条正在存储" << endl; } void MGMemory::storage () { cout << "镁光内存条正在存储" << endl; }
1 2 3 4 5 6 7 8 9 10 #include <iostream> #include "Computer.h" using namespace std;int main () { Computer computer (new IntelCPU, new ZQMemory, new AMDGPU) ; computer.work (); return 0 ; }
# 模板
C++ 另一种编程思想称为泛型编程 ,主要利用的技术就是模板
C++ 提供两种模板机制:函数模板 和类模板
# 调用规则
1. 如果函数模板和普通函数都可以实现,优先调用普通函数。
2. 可以通过空模板参数列表来强制调用函数模板。
3. 函数模板也可以发生重载。
4. 如果函数模板可以产生更好的匹配,优先调用函数模板。
# 函数模板语法
1 2 3 4 5 template <typename T>函数声明或定义
案例 1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 include<iostream> using namespace std;template <typename T>void swapNum (T& a, T& b) { T temp = a; a = b; b = temp; } int main () { int a = 10 , b = 20 ; swapNum <int >(a, b); cout << "a=" << a << "\tb=" << b << endl; }
案例 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <iostream> using namespace std;template <class T >void selectionSort (T arr[],int len) { for (int i = 0 ; i < len; i++) { int max = i; for (int j = i + 1 ; j < len; j++) { if (arr[max] < arr[j]) { max = j; } } if (max != i) { T temp = arr[i]; arr[i] = arr[max]; arr[max] = temp; } } } template <class T >void print (T arr[], int len) { for (int i = 0 ; i < len; i++) { cout << arr[i]; } cout << endl; } void test01 () { char charArr[] = "badcfe" ; int len = sizeof (charArr) / sizeof (charArr[0 ]); selectionSort (charArr, len); print (charArr, len); } void test02 () { int intArr[] = {6 ,8 ,2 ,1 ,4 ,6 ,3 ,8 ,7 ,9 }; int len = sizeof (intArr) / sizeof (intArr[0 ]); selectionSort (intArr, len); print (intArr, len); } int main () { test01 (); test02 (); system ("pause" ); }
# 类模板语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 template <class NameType , class AgeType = int >class Person {public : Person (NameType name, AgeType age) { this ->m_Name = name; this ->m_Age = age; } void showPerson () ; NameType m_Name; AgeType m_Age; }; template <class T1 , class T2 >void Person<T1, T2>::showPerson () { cout << "Person_Name:" << this ->m_Name << "\tPerson_Age:" << this ->m_Age << endl; } void test () { Person<string, int > p1 ("Michael" , 18 ) ; p1.showPerson ();; } int main () { test (); system ("pause" ); return 0 ; }
# 模板重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Person {public : Person (string name, int age) :m_Name (name), m_Age (age) {}; string m_Name; int m_Age; }; template <class T >bool myCompare (T& a, T& b) { if (a == b) return true ; else return false ; } template <> bool myCompare (Person& p1, Person& p2) { if (p1.m_Name == p2.m_Name && p1.m_Age == p2.m_Age) return true ; else return false ; } void test () { Person p1 ("Michael" , 18 ) ; Person p2 ("Michael" , 18 ) ; if (myCompare (p1, p2)) cout << "p1 == p2" << endl; } int main () { test (); system ("pause" ); return 0 ; }
# 类模板与继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 template <class AgeType >class Base {public : AgeType base_Age; }; class C1 :public Base<int > {public : C1 (int age) { this ->base_Age = age; this ->c1_Age = age; } int c1_Age; }; template <class AgeType >class C2 :public Base<AgeType> {public : C2 (AgeType age) { this ->base_Age = age; this ->c2_Age = age; } AgeType c2_Age; }; void test () { C1 c1 (18 ) ; C2<int > c2 (20 ) ; cout << "C1:" << "\tbase_Age:" << c1.base_Age << "\tc1_Age:" << c1.c1_Age << endl; cout << "C2:" << "\tbase_Age:" << c2.base_Age << "\tc2_Age:" << c2.c2_Age << endl; } int main () { test (); system ("pause" ); return 0 ; }
# 类模板案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 #pragma once #include <iostream> #include <string> using namespace std;template <class DataType >class MyArray {private : DataType* pAddress; int m_Count; int m_Size; public : MyArray (int Size) { this ->m_Count = 0 ; this ->m_Size = Size; this ->pAddress = new DataType[this ->m_Size]; } ~MyArray () { if (pAddress != NULL ) { delete [] this ->pAddress; this ->pAddress = NULL ; } } MyArray (const MyArray& arr) { this ->m_Count = arr.m_Count; this ->m_Size = arr.m_Size; this ->pAddress = new DataType[arr.m_Size]; for (int i = 0 ; i < this ->m_Count; i++) { this ->pAddress[i] = arr.pAddress[i]; } } MyArray& operator =(const MyArray& arr) { if (this ->pAddress != NULL ) { delete [] this ->pAddress; this ->pAddress = NULL ; this ->m_Count = 0 ; this ->m_Size = 0 ; } this ->m_Count = arr.m_Count; this ->m_Size = arr.m_Size; this ->pAddress = new DataType[arr.m_Size]; for (int i = 0 ; i < this ->m_Count; i++) { this ->pAddress[i] = arr.pAddress[i]; } return *this ; } void Push_Back (const DataType& val) { if (this ->m_Count == this ->m_Size) { cout << "Array Full!" << endl; return ; } this ->pAddress[this ->m_Count] = val; this ->m_Count++; } void Pop_Back () { if (this ->m_Count == 0 ) { return ; } this ->m_Count--; } DataType& operator [](int index) { if (index > this ->m_Count - 1 ) { this ->m_Count++; } return this ->pAddress[index]; } int getSize () { return this ->m_Size; } int getCount () { return this ->m_Count; } };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #include <iostream> #include <string> #include "MyArray.hpp" using namespace std;class Person {public : Person () {}; Person (string name, int age) :m_name (name), m_age (age) {}; void show () { cout << "name: " << this ->m_name << "\tage: " << this ->m_age << endl; } string m_name; int m_age; }; void test () { MyArray<int > arr (5 ) ; for (int i = 0 ; i < arr.getSize (); i++) { arr[i] = i; } for (int i = 0 ; i < arr.getSize (); i++) { cout << arr[i] << endl; } cout << arr.getCount () << "\t" << arr.getSize () << endl; arr.Pop_Back (); cout << arr.getCount () << "\t" << arr.getSize () << endl; arr.Push_Back (500 ); cout << arr.getCount () << "\t" << arr.getSize () << endl; MyArray<Person> pArr (3 ) ; Person p1 ("Michael" , 18 ) ; Person p2 ("zhangsan" , 19 ) ; Person p3 ("lisi" , 20 ) ; pArr[0 ] = p1; pArr[1 ] = p2; pArr[2 ] = p3; for (int i = 0 ; i < pArr.getCount (); i++) { pArr[i].show (); } } int main () { test (); system ("pause" ); return 0 ; }
# STL
# STL 基本概念
STL(Standard Template Library)
STL 从广义上分为:容器 (container)、算法 (algorithm)、迭代器 (iterator)
迭代器 是容器 和算法 的桥梁
STL 几乎所有代码都采用了模板类,或者模板函数
STL 六大组件:容器、算法、迭代器、仿函数、适配器 (配接器)、空间配置器
容器:各种数据结构,如 vector、list、deque、set、map 等,用于存放数据
算法:各种常用算法,如 sort、find、copy、for_each 等
迭代器:扮演了容器与算法之间的胶合剂
仿函数:行为类似函数,可作为算法的某种策略
适配器:一种用来修饰容器、仿函数或者迭代器接口的东西
空间配置器:负责空间的配置与管理
# Vector 容器
# Vector 容器语法
C++ STL 中的 verctor 好比是 C 语言中的数组,但是 vector 又具有数组没有的一些高级功能。与数组相比,vector 就是一个可以不用再初始化就必须制定大小的边长数组,当然了,它还有许多高级功能。
Vector 也称为单端数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> #include <vector> using namespace std;int main () { vector<type> vectorName; push_back (element); vector[i]; begin (); end (); size (); resize (val); capacity (); clear (); reserve (val); insert (); pop_back (); erase (element_it); swap (vec); assign (); }
# Vector 容器的使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <iostream> #include <string> #include <vector> #include <algorithm> using namespace std;void myPrint (int val) { cout << val << endl; } void test () { vector<int > v; for (int i = 0 ; i < 100 ; i += 10 ) { v.push_back (i); } for_each(v.begin (), v.end (), myPrint); } int main () { test (); system ("pause" ); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> #include <string> #include <vector> using namespace std;class Person {public : string m_name; int m_age; Person (string name, int age) :m_name (name), m_age (age) {}; }; void test () { vector<Person> v; string nameSeed[] = { "张三" ,"李四" ,"王五" }; for (int i = 0 ; i < 3 ; i++) { Person p (nameSeed[i], 18 ) ; v.push_back (p); } for (vector<Person>::iterator it = v.begin (); it != v.end (); it++) { cout << "name:" << it->m_name << "\tage:" << it->m_age << endl; } } int main () { test (); system ("pause" ); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 void test () { vector< vector<int > > vBase; vector<int > v1; vector<int > v2; vector<int > v3; for (int i = 0 ; i < 3 ; i++) { v1.push_back (i); v2.push_back (i); v3.push_back (i); } vBase.push_back (v1); vBase.push_back (v2); vBase.push_back (v3); for (vector<vector<int >>::iterator itBase = vBase.begin (); itBase != vBase.end (); itBase++) { for (vector<int >::iterator it = itBase->begin (); it != itBase->end (); it++) { cout << *it << endl; } } } int main () { test (); system ("pause" ); return 0 ; }
# String 容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 #include <iostream> #include <string> using namespace std;void test01 () { string str1 = "abcdefg" ; int pos = str1.find ("de" ); if (pos == -1 ) { cout << "value is not found" << endl; } else { cout << "value's index is " << pos << endl; } } void test02 () { string str1 = "abcdefg" ; str1.replace (1 , 3 , "1111" ); cout << "str1=" << str1 << endl; } void test03 () { string str1 = "hello" ; string str2 = "hello" ; string str3 = "xello" ; if (str1.compare (str2) == 0 ) { cout << "str1 == str2" << endl; } if (str1.compare (str3) < 0 ) { cout << "str1 < str3" << endl; } } void test04 () { string str = "Hello World" ; for (int i = 0 ; i < str.size () - 1 ; i++) { str[i] = str.at (i + 1 ); cout << str.at (i); } cout << endl; } void test05 () { string str = "hello" ; str.insert (1 , "111" ); cout << str << endl; str.erase (1 , 3 ); cout << str << endl; } void test06 () { string email = "[email protected] " ; int pos = email.find ("@" ); string usrName = email.substr (0 , pos); cout << usrName << endl; } int main () { test01 (); test02 (); test03 (); test04 (); test05 (); test06 (); system ("pause" ); return 0 ; }
# Deque 容器
vector 对于头部的插入、删除效率低,数据量越大,效率越低
deque 相对而言,对头部的插入、删除速度会比 vector 快
vector 访问元素时的速度会比 deque 快
# Deque 容器语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <deque> using namespace std;int main () { deque<type> dequeName; push_back (); push_front (); pop_back (); pop_front (); insert (); front (); back (); size (); resize (); empty (); assign (); sort (iterator begin,iterator end); clear (); return 0 ; }
# Stack 容器
# Stack 容器语法
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stack> #include <iostream> using namespace std;int main () { stack<type> stackName; stackName.empty (); stackName.size (); stackName.top (); stackName.pop (); stackName.push (); return 0 ; }
# Queue 容器
# Queue 容器语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <iostream> #include <queue> using namespace std;int main () { queue<type> queueName; queueName.empty (); queueName.size (); queueName.pop (); queueName.front (); queueName.push (); queueName.back (); return 0 ; }
# list 容器
list 翻译为列表,C++ 中的列表相当于链表 (Link List),包含数据域和指针域
STL 提供的链表是双向循环链表
# list 容器语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <iostream> #include <list> using namespace std;int main () { list<type> listName; begin (); end (); push_front (); push_back (); empty (); resize (); clear (); front (); back (); pop_front (); pop_back (); assign (); swap (); reverse (); merge (); insert (); erase (); sort (); return 0 ; }
# set/multiset 容器
set/multiset 容器又称为集合容器
元素插入容器时,会自动被排序。
set/multiset 属于关联式容器 ,底层结构是用二叉树实现的
set 和 multiset 区别:
set 不允许容器中有重复元素
multiset 允许容器中有重复元素
# set/multiset 容器语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <iostream> #include <set> using namespace std;int main () { set<Type> setName; size (); empty (); swap (s2); insert (val); clear (); erase (pos); erase (beg,end); erase (val); find (key); count (key); }
# set 容器排序
set 容器默认排序规则为从升序,可以使用仿函数改变 set 容器的排序规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <iostream> #include <set> using namespace std;class MySort {public : bool operator () (int v1, int v2) const { return v1 > v2; } }; void test () { set<int , MySort> s; s.insert (10 ); s.insert (20 ); s.insert (30 ); for (set<int , MySort>::iterator it = s.begin (); it != s.end (); it++) { cout << *it << "\t" ; } } int main () { test (); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <iostream> #include <set> using namespace std;class Person {public : Person (string name, int age) { this ->m_name = name; this ->age = age; } string m_name; int age; }; class ComparePerson {public : bool operator () (const Person& p1, const Person& p2) const { return p1.age > p2.age; } }; void test () { set<Person, ComparePerson> s; Person p1 ("Michael" , 18 ) ; Person p2 ("John" , 19 ) ; Person p3 ("Mike" , 20 ) ; s.insert (p1); s.insert (p2); s.insert (p3); for (set<Person, ComparePerson>::iterator it = s.begin (); it != s.end (); it++) { cout << "name:" << it->m_name << "\tage:" << it->age << endl; } } int main () { test (); return 0 ; }
# pair (对组)
# pair 语法
1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> using namespace std;int main () { pair<type1, type2> pairName (type1Data, type2Data) ; pair<type1, type2> pairName = make_pair (type1Data, type2Data); return 0 ; }
# pair 与 set
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iostream> #include <set> using namespace std;void test () { set<int > s; s.insert (10 ); pair<set<int >::iterator,bool > ret = s.insert (10 ); if (ret.second) { cout << "插入成功" << endl; } else { cout << "插入失败" << endl; } } int main () { test (); return 0 ; }
# map/multimap 容器
# 简介:
map 中所有元素都是 pair
pair 中第一个元素为 key (键值),起到索引作用,第二个元素为 value (实值)
所有元素都会根据元素的 key (键值) 自动排序
# 本质:
map/multimap 属于关联式容器,底层结构使用二叉树实现
# 优点:
# map 和 multimap 区别:
map 不允许容器中有重复的 key
multimap 允许容器中有重复的 key
# map/multimap 容器语法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 map<T1, T2> mapNmae; map2 (map);map3 = map2; #include <iostream> #include <map> using namespace std;void printMap (map<int , int >& m) { for (map<int , int >::iterator it = m.begin (); it != m.end (); it++) { cout << "key:" << it->first << "\tvalue:" << it->second << endl; } } void test () { map<int , int > m; m.insert (pair <int , int >(2 , 20 )); m.insert (make_pair (1 , 10 )); m.insert (map<int , int >::value_type (3 , 30 )); m[4 ] = 40 ; printMap (m); } int main () { test (); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 int main () { map<keyType, valueType> mapName; size (); empty (); swap (map); insert (elem); clear (); erase (pos); erase (beg,end); erase (key); find (key); count (key); }
# map 容器排序规则重载:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> #include <map> using namespace std;class MyCompare {public : bool operator () (int v1, int v2) const { return v1 > v2; } }; void printMap (map<int , int , MyCompare>& m) { for (map<int , int , MyCompare>::iterator it = m.begin (); it != m.end (); it++) { cout << "key:" << it->first << "\tvalue:" << it->second << endl; } } void test () { map<int , int , MyCompare> m; m.insert (pair <int , int >(2 , 20 )); m.insert (make_pair (1 , 10 )); m.insert (map<int , int >::value_type (3 , 30 )); printMap (m); } int main () { test (); return 0 ; }
# 迭代器
要访问顺序容器和关联容器中的元素,需要通过 “迭代器(iterator)” 进行。
迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。
迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# STL - 函数对象 (仿函数)
# 仿函数概念
重载函数调用操作符 的类,其对象常称为函数对象
函数对象 使用重载的 () 时,行为类似函数调用,也叫仿函数
** 本质:** 函数对象 (仿函数) 是一个类,而不是一个函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <iostream> using namespace std;class MyAdd {public : MyAdd () { this ->count = 0 ; } int operator () (int v1, int v2) { this ->count++; return v1 + v2; } int count; }; void test () { MyAdd myAdd; cout << myAdd (10 , 20 ) << endl; cout << myAdd.count << endl; } int main () { test (); system ("pause" ); return 0 ; }
# 谓词
返回 bool 类型的仿函数称为谓词
如果 operator () 接受一个参数,叫做一元谓词
如果 operator () 接收两个参数,叫做二元谓词
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #include <iostream> #include <vector> #include <algorithm> using namespace std;class GreaterFive {public : bool operator () (int val) { return val > 5 ; } }; void test01 () { vector<int > v; for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } vector<int >::iterator it = find_if (v.begin (), v.end (), GreaterFive ()); cout << *it << endl; } class MyCompare {public : bool operator () (int v1,int v2) { return v1 > v2; } }; void test02 () { vector<int > v; v.push_back (10 ); v.push_back (20 ); v.push_back (40 ); v.push_back (50 ); v.push_back (30 ); sort (v.begin (), v.end (), MyCompare ()); for (vector<int >::iterator it = v.begin (); it != v.end (); it++) { cout << *it << "\t" ; } } int main () { test01 (); test02 (); system ("pause" ); return 0 ; }
# STL 内建函数对象
使用内建函数对象时,需要引入头文件 <functional>
# 算术仿函数
1 2 3 4 5 6 7 8 template <class T > T plus<T> template <class T > T minus<T> template <class T > T multiplies<T> template <class T > T divides<T> template <class T > T modulus<T> template <class T > T negate<T>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <iostream> #include <functional> using namespace std;void test () { negate<int > n; cout << n (50 ) << endl; plus<int > p; cout << p (10 , 20 ) << endl; } int main () { test (); system ("pause" ); return 0 ; }
# 关系仿函数
1 2 3 4 5 6 7 template <class T > bool equal_to<T> template <class T > bool not_equal_to<T> template <class T > bool greater<T> template <class T > bool greater_equal<T> template <class T > bool less<T> template <class T > bool less_equal<T>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream> #include <vector> #include <algorithm> #include <functional> using namespace std;#define COUNT 5 void test () { vector<int > v; for ( int i = 0 ; i < COUNT; i++) { v.push_back (rand () % 500 ); } sort (v.begin (), v.end (), greater <int >()); for (vector<int >::iterator it = v.begin (); it != v.end (); it++) { cout << *it << "\t" ; } } int main () { test (); return 0 ; }
# 逻辑仿函数
1 2 3 4 template <class T > bool logical_and<T> template <class T > bool logical_or<T> template <class T > bool logical_not<T>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> #include <vector> #include <algorithm> #include <functional> using namespace std;void test () { vector<bool > v; v.push_back (true ); v.push_back (false ); v.push_back (true ); v.push_back (false ); for (vector<bool >::iterator it = v.begin (); it != v.end (); it++) { cout << *it << "\t" ; } cout << endl; vector<bool > v2; v2.resize (v.size ()); transform (v.begin (), v.end (), v2.begin (), logical_not <bool >()); for (vector<bool >::iterator it = v2.begin (); it != v2.end (); it++) { cout << *it << "\t" ; } } int main () { test (); return 0 ; }
# STL 常用算法
# for_each
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> #include <vector> #include <algorithm> using namespace std;void print (int val) { cout << val << "\t" ; } class MyPrint {public : void operator () (int val) { cout << val << "\t" ; } }; void test () { vector<int > v; for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } for_each(v.begin (), v.end (), MyPrint ()); } int main () { test (); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <iostream> #include <vector> #include <algorithm> using namespace std;void print (int val) { cout << val << "\t" ; } class MyPrint {public : int operator () (int val) { return val + 1 ; } }; void test () { vector<int > v; for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } vector<int > vTarget; vTarget.resize (v.size ()); transform (v.begin (), v.end (), vTarget.begin (), MyPrint ()); for_each(vTarget.begin (), vTarget.end (), print); } int main () { test (); return 0 ; }
# 查找算法
1 2 3 4 5 6 7 find; find_if; adjacent_find; binar_search; count; count_if;
# find:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std;class Person {public : Person (string name,int age) { this ->m_name = name; this ->age = age; } bool operator == (const Person& p) { if (this ->m_name == p.m_name && this ->age == p.age) return true ; return false ; } string m_name; int age; }; void test01 () { vector<int > v; for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } vector<int >::iterator it = find (v.begin (), v.end (), 5 ); if (it == v.end ()) cout << "not found" ; else cout << *it << "存在" ; } void test02 () { vector<Person> v; v.push_back (Person ("aaa" , 10 )); v.push_back (Person ("bbb" , 20 )); v.push_back (Person ("ccc" , 30 )); v.push_back (Person ("ddd" , 40 )); vector<Person>::iterator it = find (v.begin (), v.end (), Person ("bbb" , 20 )); if (it == v.end ()) cout << "not found" ; else cout << it->m_name << "\t" << it->age; } int main () { test02 (); return 0 ; }
# find_if:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std;class GreaterFive {public : bool operator () (int val) { return val > 5 ; } }; class Person {public : Person (string name, int age) { this ->m_name = name; this ->age = age; } string m_name; int age; }; class Greater20 {public : bool operator () (Person& p) { if (p.age > 20 ) return true ; return false ; } }; void test01 () { vector<int > v; for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } vector<int >::iterator it = find_if (v.begin (), v.end (), GreaterFive ()); if (it == v.end ()) cout << "not found" ; else cout << *it; cout << endl; } void test02 () { vector<Person> v; v.push_back (Person ("aaa" , 10 )); v.push_back (Person ("bbb" , 20 )); v.push_back (Person ("ccc" , 30 )); v.push_back (Person ("ddd" , 40 )); vector<Person>::iterator it = find_if (v.begin (), v.end (), Greater20 ()); if (it == v.end ()) cout << "not found" ; else cout << it->m_name << "\t" << it->age; } int main () { test01 (); test02 (); return 0 ; }
# adjacent_find:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std;void test01 () { vector<int > v; v.push_back (10 ); v.push_back (120 ); v.push_back (103 ); v.push_back (10 ); v.push_back (10 ); v.push_back (103 ); vector<int >::iterator it = adjacent_find (v.begin (), v.end ()); if (it == v.end ()) cout << "not found" ; else cout << *it; cout << endl; } int main () { test01 (); return 0 ; }
# binary_search:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream> #include <vector> #include <algorithm> using namespace std;void test01 () { vector<int > v; for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } bool ret = binary_search (v.begin (), v.end (), 9 ); if (ret) cout << "9存在" ; else cout << "9不存在" ; } int main () { test01 (); return 0 ; }
# count:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std;class Person {public : Person (string name, int age) { this ->m_name = name; this ->age = age; } bool operator == (const Person& p) { if (this ->m_name == p.m_name && this ->age == p.age) return true ; return false ; } string m_name; int age; }; void test01 () { vector<int > v; v.reserve (22 ); for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } for (int i = 0 ; i < 5 ; i++) { v.push_back (i); } for (int i = 0 ; i < 7 ; i++) { v.push_back (i); } int num = count (v.begin (), v.end (), 6 ); cout << "6的个数为:" << num << endl; } void test02 () { vector<Person> v; v.push_back (Person ("aaa" , 10 )); v.push_back (Person ("bbb" , 20 )); v.push_back (Person ("aaa" , 10 )); v.push_back (Person ("ccc" , 40 )); v.push_back (Person ("aaa" , 30 )); Person p ("aaa" , 10 ) ; int num = count (v.begin (), v.end (), p); cout << "与p相同的人共有:" << num << "个" << endl; } int main () { test01 (); test02 (); return 0 ; }
# count_if:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std;class GreaterFive {public : bool operator () (const int & val) { return val > 5 ; } }; class Person {public : Person (string name, int age) { this ->m_name = name; this ->age = age; } bool operator == (const Person& p) { if (this ->m_name == p.m_name && this ->age == p.age) return true ; return false ; } string m_name; int age; }; class AgeGreater20 {public : bool operator () (const Person& p) { if (p.age > 20 ) return true ; return false ; } }; void test01 () { vector<int > v; v.reserve (22 ); for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } for (int i = 0 ; i < 5 ; i++) { v.push_back (i); } for (int i = 0 ; i < 7 ; i++) { v.push_back (i); } int num = count_if (v.begin (), v.end (), GreaterFive ()); cout << "大于5的元素的个数为:" << num << endl; } void test02 () { vector<Person> v; v.push_back (Person ("aaa" , 10 )); v.push_back (Person ("bbb" , 20 )); v.push_back (Person ("ccc" , 30 )); v.push_back (Person ("ddd" , 40 )); v.push_back (Person ("eee" , 50 )); int num = count_if (v.begin (), v.end (), AgeGreater20 ()); cout << "年龄大于20的人共有:" << num << "个" << endl; } int main () { test01 (); test02 (); return 0 ; }
# 排序算法
1 2 3 4 5 sort (itBegin, itEnd, _Pred); random_shuffle (itBegin, itEnd); merge (itBeg1, itEnd1, itBeg2, itEnd2, itTarget);reverse (itBeg, itEnd);
# sort:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream> #include <vector> #include <algorithm> #include <string> #include <functional> using namespace std;void myPrint (int val) { cout << val << " " ; } void test01 () { vector<int > v; for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } for (int i = 0 ; i < 5 ; i++) { v.push_back (i); } for (int i = 0 ; i < 7 ; i++) { v.push_back (i); } sort (v.begin (), v.end ()); for_each(v.begin (), v.end (), myPrint); cout << endl; sort (v.begin (), v.end (), greater <int >()); for_each(v.begin (), v.end (), myPrint); } int main () { test01 (); return 0 ; }
# random_shuffle:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <vector> #include <algorithm> #include <ctime> #include <cstdlib> using namespace std;void myPrint (int val) { cout << val << " " ; } void test01 () { vector<int > v; for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } random_shuffle (v.begin (), v.end ()); for_each(v.begin (), v.end (), myPrint); } int main () { srand ((unsigned )time (NULL )); test01 (); return 0 ; }
merge:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> #include <vector> #include <algorithm> using namespace std;void myPrint (int val) { cout << val << " " ; } void test01 () { vector<int > v1; vector<int > v2; for (int i = 0 ; i < 10 ; i++) { v1.push_back (i); v2.push_back (i + 1 ); } vector<int > vTarget; vTarget.resize (v1.size () + v2.size ()); merge (v1.begin (), v1.end (), v2.begin (), v2.end (), vTarget.begin ()); for_each(vTarget.begin (), vTarget.end (), myPrint); } int main () { test01 (); return 0 ; }
# reverse:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <vector> #include <algorithm> using namespace std;void myPrint (int val) { cout << val << " " ; } void test01 () { vector<int > v; for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } cout << "反转前:" << endl; for_each(v.begin (), v.end (), myPrint); reverse (v.begin (), v.end ()); cout << "反转后:" << endl; for_each(v.begin (), v.end (), myPrint); } int main () { test01 (); return 0 ; }
# 拷贝与替换算法
1 2 3 4 5 copy (itBeg, itEnd, itTargetBeg); replace (itBeg, itEnd, oldVal, newVal); replace_if (itBeg, itEnd, _Pred, newVal);swap (container c1, container c2);
# copy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream> #include <vector> #include <algorithm> using namespace std;void myPrint (int val) { cout << val << " " ; } void test01 () { vector<int > v1; for (int i = 0 ; i < 10 ; i++) { v1.push_back (i); } vector<int > v2; v2.resize (v1.size ()); copy (v1.begin (), v1.end (), v2.begin ()); for_each(v2.begin (), v2.end (), myPrint); } int main () { test01 (); return 0 ; }
# replace:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> #include <vector> #include <algorithm> using namespace std;void myPrint (int val) { cout << val << " " ; } void test01 () { vector<int > v; for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } cout << "替换前:" << endl; for_each(v.begin (), v.end (), myPrint); cout << endl; replace (v.begin (), v.end (), 2 , 20 ); cout << "替换后:" << endl; for_each(v.begin (), v.end (), myPrint); } int main () { test01 (); return 0 ; }
# replace_if:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <iostream> #include <vector> #include <algorithm> using namespace std;void myPrint (int val) { cout << val << " " ; } class GreaterFive {public : bool operator () (int val) { if (val > 5 ) return true ; return false ; } }; void test01 () { vector<int > v; for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } for (int i = 0 ; i < 10 ; i++) { v.push_back (i); } cout << "替换前:" << endl; for_each(v.begin (), v.end (), myPrint); cout << endl; replace_if (v.begin (), v.end (), GreaterFive (), 10 ); cout << "替换后:" << endl; for_each(v.begin (), v.end (), myPrint); } int main () { test01 (); return 0 ; }
# swap:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <iostream> #include <vector> #include <algorithm> using namespace std;void myPrint (int val) { cout << val << " " ; } void test01 () { vector<int > v1; vector<int > v2; for (int i = 0 ; i < 10 ; i++) { v1.push_back (i); v2.push_back (i * 10 ); } cout << "交换前:" << endl; for_each(v1.begin (), v1.end (), myPrint); cout << endl; for_each(v2.begin (), v2.end (), myPrint); cout << endl; swap (v1, v2); cout << "交换后:" << endl; for_each(v1.begin (), v1.end (), myPrint); cout << endl; for_each(v2.begin (), v2.end (), myPrint); cout << endl; } int main () { test01 (); return 0 ; }
# 算术生成算法 (numeric)
# accumulate:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 accumulate (itBeg, itEnd, value);#include <iostream> #include <vector> #include <numeric> using namespace std;void test01 () { vector<int > v; for (int i = 1 ; i < 101 ; i++) { v.push_back (i); } int result = accumulate (v.begin (), v.end (), 0 ); cout << result; } int main () { test01 (); return 0 ; }
(6.2)fill:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 fill (itBeg, itEnd, value);#include <iostream> #include <vector> #include <numeric> using namespace std;void test01 () { vector<int > v; v.resize (10 ); fill (v.begin (), v.end (), 100 ); for (vector<int >::iterator it = v.begin (); it != v.end (); it++) { cout << *it << "\t" ; } } int main () { test01 (); return 0 ; }
# 常用集合算法
1 2 3 4 5 set_intersection (beg1,end1,beg2,end2,begTar); set_union (beg1,end1,beg2,end2,begTar); set_difference (beg1,end1,beg2,end2,begTar);
# set_intersection:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <iostream> #include <vector> #include <algorithm> using namespace std;void test01 () { vector<int > v1; vector<int > v2; for (int i = 0 ; i < 10 ; i++) { v1.push_back (i); } for (int i = 5 ; i < 15 ; i++) { v2.push_back (i); } vector<int > vT; vT.resize (min (v1.size (), v2.size ())); vector<int >::iterator itEnd = set_intersection (v1.begin (), v1.end (), v2.begin (), v2.end (), vT.begin ()); for (vector<int >::iterator it = vT.begin (); it != itEnd; it++) { cout << *it << "\t" ; } } int main () { test01 (); return 0 ; }
# set_union:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> #include <vector> #include <algorithm> using namespace std;void test01 () { vector<int > v1; vector<int > v2; for (int i = 0 ; i < 10 ; i++) { v1.push_back (i); } for (int i = 5 ; i < 15 ; i++) { v2.push_back (i); } vector<int > vT; vT.resize (v1.size () + v2.size ()); vector<int >::iterator itEnd = set_union (v1.begin (), v1.end (), v2.begin (), v2.end (), vT.begin ()); for (vector<int >::iterator it = vT.begin (); it != itEnd; it++) { cout << *it << "\t" ; } } int main () { test01 (); return 0 ; }
# set_difference:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> #include <vector> #include <algorithm> using namespace std;void test01 () { vector<int > v1; vector<int > v2; for (int i = 0 ; i < 20 ; i++) { v1.push_back (i); } for (int i = 5 ; i < 15 ; i++) { v2.push_back (i); } vector<int > vT; vT.resize (max (v1.size (), v2.size ())); vector<int >::iterator itEnd = set_difference (v1.begin (), v1.end (), v2.begin (), v2.end (), vT.begin ()); for (vector<int >::iterator it = vT.begin (); it != itEnd; it++) { cout << *it << "\t" ; } } int main () { test01 (); return 0 ; }
# 文件读写
C++ 中对文件操作需要包含头文件 <fstream>
文件类型分为两种:
** 文本文件 - ** 文件以文本的 ASCII 码 形式存储在计算机中。
** 二进制文件 - ** 文件以文本的二进制 形式存储在计算机中,用户一般不能直接读懂它们。
操作文件分为三大类:
1.ofstrean:写操作
2.ifstream:读操作
3.fstream:读写操作
# 文件打开方式
打开方式
解释
ios::in
为读文件而打开文件
ios::out
为写文件而打开文件
ios::ate
初始位置:文件尾
ios::app
追加方式写文件
ios::trunc
如果文件存在,先删除,再创建
ios::binary
二进制方式
注:文件打开方式可以配合使用,利用 | 操作符。
例如:用二进制方式写文件:ios::binary | ios::out
# 写文件
步骤如下:
1. 包含头文件
2. 创建流对象 // 如:ofstream ofs;
3. 打开文件 // 如:ofs.open (“filePath”,openStyle);
4. 写数据 // 如:ofs <<“写入数据”;
5. 关闭文件 // 如:ofs.close ();
1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> #include <fstream> using namespace std;int main () { ofstream ofs; ofs.open ("./test.txt" , ios::out); ofs << "测试文本1" << endl; ofs << "测试文本2" << endl; ofs.close (); return 0 ; }
# 读文件
步骤如下:
1. 包含头文件
2. 创建流对象
3. 打开文件,并判断是否打开成功
4. 读数据
5. 关闭文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <iostream> #include <fstream> using namespace std;int main () { ifstream ifs; ifs.open ("./test.txt" , ios::in); if (!ifs.is_open ()) { cout << "文件打开失败" << endl; return 0 ; } string buf; while (getline (ifs, buf)) { cout << buf << endl; } ifs.close (); return 0 ; }
# 二进制形式读写文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> #include <fstream> using namespace std;class Person {public : char m_Name[64 ]; int m_Age; }; int main () { Person p = { "张三" , 18 }; fstream fs; fs.open ("./Person.txt" , ios::out | ios::binary); fs.write ((const char *)&p, sizeof (Person)); fs.close (); fs.open ("./Person.txt" , ios::in | ios::binary); if (!fs.is_open ()) { cout << "文件打开失败!" << endl; return 0 ; } Person p2; fs.read ((char *)&p2, sizeof (Person)); cout << "姓名" << p2.m_Name << "\t" << "年龄" << p2.m_Age << endl; fs.close (); return 0 ; }
# 案例
# 职工管理系统
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include "wokerManager.h" int main () { wokerManager wm; while (true ) { wm.start (); char key = wm.cinFunction (1 ); switch (key) { case '0' : wm.end (); break ; case '1' : wm.addEmp (); break ; case '2' : wm.showInfo (); break ; case '3' : wm.deleteEmp (); break ; case '4' : wm.mod_Emp (); break ; case '5' : wm.find_Emp (); break ; case '6' : wm.sort_Emp (); break ; case '7' : wm.renameId (); break ; case '8' : wm.clear (); break ; } system ("pause" ); system ("cls" ); } return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #pragma once #include <iostream> #include <fstream> #include "Woker.h" #include "Employee.h" #include "Manager.h" #include "Boss.h" using namespace std;#define FILENAME "empFile.txt" class wokerManager { public : wokerManager (); ~wokerManager (); char cinFunction (int mod) ; void start () ; void end () ; void addEmp () ; void showInfo () ; Woker** loadFile () ; void save () ; int getEmpNum () ; void deleteEmp () ; int isExist (int id) ; void mod_Emp () ; void find_Emp () ; void sort_Emp () ; void clear () ; void Sort (int mod) ; void renameId () ; int empNum; Woker** wokerArr; bool m_FileIsEmpty; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 #include "wokerManager.h" wokerManager::wokerManager () { ifstream ifs; ifs.open (FILENAME, ios::in); if (!ifs.is_open ()) { this ->empNum = 0 ; this ->wokerArr = NULL ; this ->m_FileIsEmpty = true ; ifs.close (); return ; } char ch; ifs >> ch; if (ifs.eof ()) { this ->empNum = 0 ; this ->wokerArr = NULL ; this ->m_FileIsEmpty = true ; ifs.close (); return ; } this ->empNum = getEmpNum (); this ->wokerArr = loadFile (); this ->m_FileIsEmpty = false ; ifs.close (); } wokerManager::~wokerManager () { if (wokerArr != NULL ) { delete [] this ->wokerArr; this ->wokerArr = NULL ; } } int wokerManager::getEmpNum () { ifstream ifs; ifs.open (FILENAME, ios::in); int id, DeptId; string name; int num = 0 ; while (ifs >> id && ifs >> name && ifs >> DeptId) { num++; } ifs.close (); return num; } void wokerManager::start () { cout << "******************************" << endl; cout << "*****欢迎使用职工管理系统!****" << endl; cout << "********0.退出管理系统********" << endl; cout << "********1.增加职工信息********" << endl; cout << "********2.显示职工信息********" << endl; cout << "********3.删除离职职工********" << endl; cout << "********4.修改职工信息********" << endl; cout << "********5.查找职工信息********" << endl; cout << "********6.按照编号排序********" << endl; cout << "********7.重置职工编号********" << endl; cout << "********8.清空所有文档********" << endl; } void wokerManager::end () { cout << "您确定要退出吗?(Y/N):" ; while (1 ) { cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); char choice; cin >> choice; if (choice == 'Y' || choice == 'y' ) { cout << "欢迎下次使用" << endl; exit (0 ); } else if (choice == 'N' || choice == 'n' ) { return ; } else { cout << "输入错误,请重新输入:" ; } } } char wokerManager::cinFunction (int mod) { cout << "请输入您的选择:" ; while (1 ) { char key; cin >> key; switch (key) { case '0' : if (mod == 2 ) break ; case '1' : case '2' : if (mod == 2 ) return key; case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : if (mod == 1 ) return key; } cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "输入错误,请重新输入:" ; } } void wokerManager::addEmp () { cout << "请输入你要添加的职工数:" ; while (true ) { int addNum = 0 ; cin >> addNum; cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); if (addNum > 0 ) { int newSize = this ->empNum + addNum; Woker** newSpace = new Woker * [newSize]; if (this ->wokerArr != NULL ) { for (int i = 0 ; i < empNum; i++) { newSpace[i] = this ->wokerArr[i]; } } for (int i = 0 ; i < addNum; i++) { int id, DeptId; string name; cout << "请输入第" << i + 1 << "个职工的编号:" ; cin >> id; cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "请输入第" << i + 1 << "个职工的姓名:" ; cin >> name; cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "请选择该职工的岗位\t" << "1.普通员工" << "2.经理" << "3.老板\t:" ; cin >> DeptId; cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); Woker* woker = NULL ; switch (DeptId) { case 1 : woker = new Employee (id, name, DeptId); break ; case 2 : woker = new Manager (id, name, DeptId); break ; case 3 : woker = new Boss (id, name, DeptId); break ; } newSpace[empNum + i] = woker; } if (this ->wokerArr != NULL ) { delete [] this ->wokerArr; this ->wokerArr = NULL ; } this ->wokerArr = newSpace; this ->empNum += addNum; save (); this ->m_FileIsEmpty = false ; cout << "添加完成!" << endl; return ; } else { cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "输入错误,请重新输入:" ; } } } void wokerManager::showInfo () { if (wokerArr == NULL ) { cout << "暂无职工信息" << endl; return ; } for (int i = 0 ; i < empNum; i++) { this ->wokerArr[i]->showInfo (); } } Woker** wokerManager::loadFile () { ifstream ifs; ifs.open (FILENAME, ios::in); int id, DeptId, index = 0 ; string name; Woker** newSpace = new Woker * [this ->empNum]; while (ifs >> id && ifs >> name && ifs >> DeptId) { Woker* woker = NULL ; switch (DeptId) { case 1 : woker = new Employee (id, name, DeptId); break ; case 2 : woker = new Manager (id, name, DeptId); break ; case 3 : woker = new Boss (id, name, DeptId); break ; } newSpace[index] = woker; index++; } ifs.close (); return newSpace; } void wokerManager::save () { ofstream ofs; ofs.open (FILENAME, ios::trunc); for (int i = 0 ; i < empNum; i++) { ofs << this ->wokerArr[i]->m_Id << "\t" << this ->wokerArr[i]->m_Name << "\t" << this ->wokerArr[i]->m_DeptId << endl; } ofs.close (); } void wokerManager::deleteEmp () { cout << "请输入要删除的职工的编号:" ; int index; cin >> index; index = isExist (index); if (index == -1 ) { cout << "职工编号未找到!" << endl; return ; } for (int i = index; i < empNum - 1 ; i++) { wokerArr[i] = wokerArr[i + 1 ]; } save (); this ->empNum--; cout << "删除成功!" << endl; } int wokerManager::isExist (int id) { int index = -1 ; for (int i = 0 ; i < this ->empNum; i++) { if (this ->wokerArr[i]->m_Id == id) { index = i; break ; } } return index; } void wokerManager::mod_Emp () { cout << "请输入要修改的职工的编号:" ; int index; cin >> index; index = isExist (index); if (index == -1 ) { cout << "职工编号未找到!" << endl; return ; } cout << "修改前信息" << endl; wokerArr[index]->showInfo (); int id, DeptId; string name; cout << "请输入修改后职工的编号:" ; cin >> id; cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "请输入修改后职工的姓名:" ; cin >> name; cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "请选择修改后职工的岗位\t" << "1.普通员工" << "2.经理" << "3.老板\t:" ; cin >> DeptId; cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); Woker* woker = NULL ; switch (DeptId) { case 1 : woker = new Employee (id, name, DeptId); break ; case 2 : woker = new Manager (id, name, DeptId); break ; case 3 : woker = new Boss (id, name, DeptId); break ; } wokerArr[index] = woker; save (); cout << "修改完成!" << endl; } void wokerManager::find_Emp () { cout << "请选择查找方式:1.按照编号、2.按照姓名:" ; char choice = cinFunction (2 ); if (choice == '1' ) { cout << "请输入职工的编号:" ; int index; cin >> index; index = isExist (index); if (index == -1 ) { cout << "职工编号未找到!" << endl; return ; } wokerArr[index]->showInfo (); return ; } else if (choice == '2' ) { cout << "请输入职工的姓名:" ; string name; cin >> name; for (int i = 0 ; i < this ->empNum; i++) { if (this ->wokerArr[i]->m_Name == name) { this ->wokerArr[i]->showInfo (); return ; } } cout << "员工未找到" << endl; } } void wokerManager::sort_Emp () { if (wokerArr == NULL ) { cout << "暂无职工信息" << endl; return ; } cout << "请输入排序方式:1.升序、2.降序:" ; char choice = cinFunction (2 ); switch (choice) { case '1' : Sort (1 ); break ; case '2' : Sort (2 ); break ; } } void wokerManager::Sort (int mod) { if (mod == 1 ) { for (int i = this ->empNum; i > 0 ; i--) { int maxIndex = 0 ; for (int j = 1 ; j < i; j++) { if (wokerArr[j]->m_Id > wokerArr[maxIndex]->m_Id) maxIndex = j; } Woker* temp = wokerArr[i - 1 ]; wokerArr[i - 1 ] = wokerArr[maxIndex]; wokerArr[maxIndex] = temp; } } else if (mod == 2 ) { for (int i = this ->empNum; i > 0 ; i--) { int maxIndex = 0 ; for (int j = 1 ; j < i; j++) { if (wokerArr[j]->m_Id < wokerArr[maxIndex]->m_Id) maxIndex = j; } Woker* temp = wokerArr[i - 1 ]; wokerArr[i - 1 ] = wokerArr[maxIndex]; wokerArr[maxIndex] = temp; } } save (); } void wokerManager::renameId () { if (this ->wokerArr == NULL ) { cout << "暂无职工信息" << endl; return ; } for (int i = 0 ; i < empNum; i++) { this ->wokerArr[i]->m_Id = i + 1 ; } save (); cout << "重置完成!" << endl; } void wokerManager::clear () { cout << "您确定要清空文件吗?(Y/N):" ; while (1 ) { cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); char choice; cin >> choice; if (choice == 'Y' || choice == 'y' ) { empNum = 0 ; save (); cout << "清除成功!" << endl; return ; } else if (choice == 'N' || choice == 'n' ) { return ; } else { cout << "输入错误,请重新输入:" ; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #pragma once #include <iostream> #include <string> using namespace std;class Woker { public : virtual void showInfo () = 0 ; virtual string getDeptName () = 0 ; int m_Id; string m_Name; int m_DeptId; };
1 2 3 4 5 6 7 8 9 10 #pragma once #include "Woker.h" class Employee :public Woker{ public : Employee (int id,string name,int DeptId); void showInfo () ; string getDeptName () ; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include "Employee.h" Employee::Employee (int id, string name, int DeptId) { this ->m_Id = id; this ->m_Name = name; this ->m_DeptId = DeptId; } void Employee::showInfo () { cout << "职工编号:" << this ->m_Id << "\t职工姓名:" << this ->m_Name << "\t职工部门:" << this ->getDeptName () << "\t职工职责:完成经理下发的任务" << endl; } string Employee::getDeptName () { return string ("员工" ); }
1 2 3 4 5 6 7 8 9 10 #pragma once #include "Woker.h" class Manager :public Woker{ public : Manager (int id, string name, int DeptId); void showInfo () ; string getDeptName () ; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include "Manager.h" Manager::Manager (int id, string name, int DeptId) { this ->m_Id = id; this ->m_Name = name; this ->m_DeptId = DeptId; } void Manager::showInfo () { cout << "职工编号:" << this ->m_Id << "\t职工姓名:" << this ->m_Name << "\t职工部门:" << this ->getDeptName () << "\t职工职责:完成老板下发的任务,并下发任务给员工" << endl; } string Manager::getDeptName () { return string ("老板" ); }
1 2 3 4 5 6 7 8 9 10 #pragma once #include "Woker.h" class Boss :public Woker{ public : Boss (int id, string name, int DeptId); void showInfo () ; string getDeptName () ; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include "Boss.h" Boss::Boss (int id, string name, int DeptId) { this ->m_Id = id; this ->m_Name = name; this ->m_DeptId = DeptId; } void Boss::showInfo () { cout << "职工编号:" << this ->m_Id << "\t职工姓名:" << this ->m_Name << "\t职工部门:" << this ->getDeptName () << "\t职工职责:管理公司所有事务" << endl; } string Boss::getDeptName () { return string ("老板" ); }
# STL 案例
# STL 案例 1:评委打分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <iostream> #include <string> #include <vector> #include <deque> #include <cstdlib> #include <ctime> #include <algorithm> using namespace std;class Competitor {public : Competitor (string name,int score) { this ->m_name = name; this ->m_score = score; } string m_name; int m_score; }; void createCompetitor (vector<Competitor>& v) { string nameSeed = "ABCDE" ; for (int i = 0 ; i < 5 ; i++) { string name = "选手" ; name += nameSeed[i]; int score = 0 ; Competitor c (name, score) ; v.push_back (c); } } void setScore (vector<Competitor>& v) { srand ((unsigned )time (NULL )); for (vector<Competitor>::iterator it = v.begin (); it != v.end (); it++) { deque<int > d; for (int i = 0 ; i < 10 ; i++) { int score = rand () % 41 + 60 ; d.push_back (score); } sort (d.begin (), d.end ()); d.pop_back (); d.pop_front (); int sum = 0 ; for (deque<int >::iterator dit = d.begin (); dit != d.end (); dit++) { sum += *dit; } int avg = sum / d.size (); it->m_score = avg; } } void myPrint (vector<Competitor>& v) { for (vector<Competitor>::iterator it = v.begin (); it != v.end (); it++) { cout << "name:" << it->m_name << "\tscore:" << it->m_score << endl; } } int main () { vector<Competitor> v; createCompetitor (v); myPrint (v); setScore (v); myPrint (v); system ("pause" ); return 0 ; }
# STL 案例 2:员工分组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 #include <iostream> #include <map> #include <vector> #include <string> #include <cstdlib> #include <ctime> using namespace std;#define WORKER_NUM 10 #define CEHUA 0 #define MEISHU 1 #define YANFA 2 class Worker {public : string m_Name; int m_Salary; }; void createWorker (vector<Worker>& v) { string nameSeed = "ABCDEFGHIJ" ; for (int i = 0 ; i < WORKER_NUM; i++) { Worker worker; worker.m_Name = "员工" ; worker.m_Name += nameSeed[i]; worker.m_Salary = rand () % 10000 + 10000 ; v.push_back (worker); } } void setGroup (vector<Worker>& v, multimap<int , Worker>& m) { for (vector<Worker>::iterator it = v.begin (); it != v.end (); it++) { int deptId = rand () % 3 ; m.insert (pair <int , Worker>(deptId, *it)); } } void showWorkerByGroup (multimap<int , Worker>& m) { if (m.begin () == m.end ()) return ; multimap<int , Worker>::iterator pos = m.find (CEHUA); int count = m.count (CEHUA), index = 0 ; cout << "策划部门:" << endl; for (; pos != m.end () && index < count; pos++, index++) { cout << "name:" << pos->second.m_Name << "\tsalary:" << pos->second.m_Salary << endl; } pos = m.find (MEISHU); count = m.count (MEISHU); index = 0 ; cout << "美术部门:" << endl; for (; pos != m.end () && index < count; pos++, index++) { cout << "name:" << pos->second.m_Name << "\tsalary:" << pos->second.m_Salary << endl; } pos = m.find (YANFA); count = m.count (YANFA); index = 0 ; cout << "研发部门:" << endl; for (; pos != m.end () && index < count; pos++, index++) { cout << "name:" << pos->second.m_Name << "\tsalary:" << pos->second.m_Salary << endl; } } int main () { srand ((unsigned )time (NULL )); vector<Worker> vWorker; createWorker (vWorker); multimap<int , Worker> mWorker; setGroup (vWorker, mWorker); showWorkerByGroup (mWorker); system ("pause" ); return 0 ; }
# 演讲比赛流程管理系统
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <iostream> #include "Competitor.h" #include "ManageSystem.h" using namespace std;int main () { srand (time (NULL )); ManageSystem ms; bool loop = true ; while (loop) { ms.StartMenu (); int key = -1 ; string temp; cin >> temp; while (!ms.IsRegexInput (temp)) { cout << "输入错误,请重新输入:" ; cin >> temp; } key = stoi (temp); switch (key) { case 0 : if (ms.Exit ()) loop = false ; break ; case 1 : ms.Start (); break ; case 2 : ms.LoadCompetitionResult (); break ; case 3 : ms.Clear (); break ; } } return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #pragma once #include <iostream> #include <string> using namespace std;class Competitor { public : Competitor (string name, float score, int number, int m_Group); void setScore (float score) ; float getScore () ; void setGroup (int group) ; int getGroup () ; void showInfo () ; int getNumber () ; private : string m_Name; float m_Score; int m_Number; int m_Group; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include "Competitor.h" Competitor::Competitor (string name, float score, int number, int Group) { this ->m_Name = name; this ->m_Score = score; this ->m_Number = number; this ->m_Group = Group; } void Competitor::setScore (float score) { this ->m_Score = score; } float Competitor::getScore () { return this ->m_Score; } void Competitor::setGroup (int group) { this ->m_Group = group; } int Competitor::getGroup () { return this ->m_Group; } void Competitor::showInfo () { cout << "选手信息:" << endl; cout << "编号:" << this ->m_Number << "\t姓名:" << this ->m_Name << "\t评分:" ; printf ("%.2f\n" , this ->m_Score); } int Competitor::getNumber () { return this ->m_Number; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #pragma once #include <iostream> #include <vector> #include <algorithm> #include <numeric> #include <ctime> #include <cstdlib> #include <deque> #include <fstream> #include <regex> #include "Competitor.h" using namespace std;#define COMPETITOR_NUM 12 #define START_NUM 10001 #define GROUP 0 #define GROUP_1 1 #define GROUP_2 2 #define GROUP_FINAL 3 #define SCORE_TIMES 10 #define PATH "./CompetitionRecord.txt" #define DATAPATH "./Data.txt" class ManageSystem { public : ManageSystem (); ~ManageSystem (); void StartMenu () ; void Start () ; void CreateCompetitor () ; void SetGroup () ; void ShowInfoByGroup () ; void SetScore () ; void UpCompetitor () ; void UpComShow () ; void FinalShow () ; void SaveData () ; void SaveResult () ; void LoadCompetitionResult () ; void Clear () ; bool Exit () ; bool IsRegexInput (string str) ; private : vector<Competitor>* ComVector; int Count; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 #include "ManageSystem.h" bool CompareByScore (Competitor& c1, Competitor& c2) { return c1.getScore () > c2.getScore (); } ManageSystem::ManageSystem () { this ->ComVector = new vector<Competitor>; ifstream ifs; ifs.open (DATAPATH, ios::in); if (!ifs.is_open ()) { this ->Count = 1 ; } else { int temp = 1 ; string sTemp; while (ifs >> sTemp); temp = stoi (sTemp); this ->Count = temp; } ifs.close (); } ManageSystem::~ManageSystem () { if (this ->ComVector != NULL ) { this ->ComVector->clear (); delete this ->ComVector; this ->ComVector = NULL ; } } void ManageSystem::StartMenu () { cout << "**************************" << endl; cout << "*****欢迎参加演讲比赛*****" << endl; cout << "******1.开始演讲比赛******" << endl; cout << "******2.查看往届记录******" << endl; cout << "******3.清空比赛记录******" << endl; cout << "******0.退出比赛程序******" << endl; cout << "**************************" << endl; cout << endl; cout << "请输入您的选择:" ; } void ManageSystem::Start () { cout << "第 << 1 >> 轮比赛选手正在抽签" << endl; cout << "---------------------------" << endl; this ->CreateCompetitor (); this ->SetGroup (); cout << "抽签后演讲顺序如下:" << endl; for (vector<Competitor>::iterator it = this ->ComVector->begin (); it != this ->ComVector->end (); it++) { cout << it->getNumber () << "\t" ; } cout << endl; cout << "---------------------------" << endl; system ("pause" ); cout << "-------------第1轮正式比赛开始-------------" << endl; this ->SetScore (); this ->ShowInfoByGroup (); cout << "-------------第1轮正式比赛结束-------------" << endl; system ("pause" ); cout << "-------------第1轮晋级选手信息-------------" << endl; this ->UpCompetitor (); this ->UpComShow (); system ("pause" ); system ("cls" ); cout << "第 << 2 >> 轮比赛选手正在抽签" << endl; cout << "---------------------------" << endl; random_shuffle (this ->ComVector->begin (), this ->ComVector->end ()); cout << "抽签后演讲顺序如下:" << endl; for (vector<Competitor>::iterator it = this ->ComVector->begin (); it != this ->ComVector->end (); it++) { if (it->getGroup () == GROUP_FINAL) cout << it->getNumber () << "\t" ; } cout << endl; cout << "---------------------------" << endl; system ("pause" ); cout << "-------------第2轮正式比赛开始-------------" << endl; this ->SetScore (); sort (this ->ComVector->begin (), this ->ComVector->end (), CompareByScore); cout << "决赛名次:" << endl; this ->UpComShow (); cout << "-------------第2轮正式比赛结束-------------" << endl; system ("pause" ); system ("cls" ); this ->FinalShow (); this ->SaveResult (); system ("pause" ); system ("cls" ); } void ManageSystem::CreateCompetitor () { string nameSeed = "ABCDEFGHIJKLMNOPQRTSUVWXYZ" ; for (int i = 0 ; i < COMPETITOR_NUM; i++) { string name = "选手" ; name += nameSeed[i]; Competitor c (name, 0 , START_NUM + i, GROUP) ; this ->ComVector->push_back (c); } } void ManageSystem::SetGroup () { random_shuffle (this ->ComVector->begin (), this ->ComVector->end ()); int count = 0 ; for (vector<Competitor>::iterator it = this ->ComVector->begin (); it != this ->ComVector->end (); it++) { if (count < COMPETITOR_NUM / 2 ) { it->setGroup (GROUP_1); count++; continue ; } it->setGroup (GROUP_2); } } void ManageSystem::ShowInfoByGroup () { cout << "第一组选手信息:" << endl; for (vector<Competitor>::iterator it = this ->ComVector->begin (); it != this ->ComVector->end (); it++) { if (it->getGroup () == GROUP_1) it->showInfo (); } cout << endl; cout << "第二组选手信息:" << endl; for (vector<Competitor>::iterator it = this ->ComVector->begin (); it != this ->ComVector->end (); it++) { if (it->getGroup () == GROUP_2) it->showInfo (); } } void ManageSystem::SetScore () { for (vector<Competitor>::iterator it = this ->ComVector->begin (); it != this ->ComVector->end (); it++) { deque<float > d; float score = 0 , sum = 0 ; for (int i = 0 ; i < SCORE_TIMES; i++) d.push_back ((float )(rand () % 40 + 61 )); sort (d.begin (), d.end ()); d.pop_front (); d.pop_back (); for (int i = 0 ; i < SCORE_TIMES - 2 ; i++) { sum += d.back (); d.pop_back (); } score = sum / (SCORE_TIMES - 2 ); it->setScore (score); } } void ManageSystem::UpCompetitor () { sort (this ->ComVector->begin (), this ->ComVector->end (), CompareByScore); int group1 = 0 , group2 = 0 ; for (vector<Competitor>::iterator it = this ->ComVector->begin (); it != this ->ComVector->end (); it++) { if (group1 < 3 && it->getGroup () == GROUP_1) { it->setGroup (GROUP_FINAL); group1++; continue ; } if (group2 < 3 && it->getGroup () == GROUP_2) { it->setGroup (GROUP_FINAL); group2++; continue ; } } } void ManageSystem::UpComShow () { for (vector<Competitor>::iterator it = this ->ComVector->begin (); it != this ->ComVector->end (); it++) { if (it->getGroup () == GROUP_FINAL) it->showInfo (); } } void ManageSystem::FinalShow () { vector<Competitor>::iterator it = this ->ComVector->begin (); cout << "冠军:" << endl; it->showInfo (); it++; cout << "亚军:" << endl; it->showInfo (); it++; cout << "季军:" << endl; it->showInfo (); } void ManageSystem::SaveData () { ofstream ofs; ofs.open (DATAPATH, ios::out | ios::trunc); ofs << this ->Count << endl; ofs.close (); } void ManageSystem::SaveResult () { ofstream ofs; ofs.open (PATH, ios::out | ios::app); if (!ofs.is_open ()) { cout << "比赛结果保存失败!" << endl; return ; } vector<Competitor>::iterator it = this ->ComVector->begin (); string rank[] = { "冠军:" ,"亚军:" ,"季军:" }; ofs << "第" << this ->Count << "届:" << endl; this ->Count++; this ->SaveData (); for (int i = 0 ; i < 3 ; i++) { ofs << rank[i] << "编号:" << it->getNumber () << "、得分:" << it->getScore () << endl; it++; } ofs.close (); cout << "比赛记录已保存,可在查看往届记录中查看" << endl; } void ManageSystem::LoadCompetitionResult () { if (this ->Count == 1 ) { cout << "暂无比赛记录" << endl; system ("pause" ); system ("cls" ); return ; } ifstream ifs; ifs.open (PATH, ios::in); if (!ifs.is_open ()) { cout << "读取失败!" << endl; return ; } string buf; while (ifs >> buf) { cout << buf << endl; } ifs.close (); system ("pause" ); system ("cls" ); } void ManageSystem::Clear () { cout << "你确认要清空往届比赛记录吗?(不可恢复!!)[Y/N]:" ; char choice = 'N' ; cin >> choice; if (choice == 'y' || choice == 'Y' ) { ofstream ofs; ofs.open (PATH, ios::trunc); ofs.close (); this ->Count = 1 ; this ->SaveData (); cout << "已全部清除!" << endl; } system ("pause" ); system ("cls" ); } bool ManageSystem::Exit () { cout << "你确认要退出吗?(Y/N):" ; char choice = 'a' ; cin >> choice; if (choice == 'y' || choice == 'Y' ) { return true ; } system ("cls" ); return false ; } bool ManageSystem::IsRegexInput (string str1) { bool flag = true ; regex r ("\\d{0,3}" ) ; while (!(flag = regex_match (str1, r))) { return flag; } return flag; }
# 机房预约系统
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
这个案例是我开始学代码到现在,代码量最大的,感觉写的很乱,很屎山。自己有都点看不下去 =.=
运行环境为 Windows11,VS2022
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream> #include "ManageSystem.h" using namespace std;int main () { ifstream ifs; ifs.open (ADMIN_PATH, ios::in); if (!ifs.is_open ()) { ifs.close (); ofstream ofs; ofs.open (ADMIN_PATH, ios::out); ofs << 9527 << " " << "Admin" << " " << "admin" ; ofs.close (); } ifs.close (); ifs.open (MACHINE_PATH, ios::in); if (!ifs.is_open ()) { ifs.close (); ofstream ofs; ofs.open (MACHINE_PATH, ios::out); ofs << 1 << " " << 20 ; ofs << 2 << " " << 50 ; ofs << 3 << " " << 100 ; ofs.close (); } ifs.close (); ManageSystem ms; int choice = -1 ; string temp; ofstream ofs; ofs.open (MACHINE_PATH, ios::out | ios::app); ofs.close (); ofs.open (RESERVATION_PATH, ios::out | ios::app); ofs.close (); while (true ) { ms.StartMenu (); cin >> temp; while (!ms.CinJudgement (temp, R_TYPE1)) { cout << "输入错误,请重新输入:" ; cin >> temp; } choice = stoi (temp); if (choice > 9 ) { choice %= 10 ; } ms.Login (choice); } system ("pause" ); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #pragma once #define STU_PATH "./StudentRepData.txt" #define TEACHER_PATH "./TeacherData.txt" #define ADMIN_PATH "./AdminData.txt" #define MACHINE_PATH "./MachineRoom.txt" #define RESERVATION_PATH "./Reservation.txt" #define R_TYPE1 1 #define R_TYPE2 2 #define R_TYPE3 3 #define R_TYPE4 4 #define STATUS_ING 1 #define STATUS_PASS 2 #define STATUS_FAIL 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #pragma once #include <iostream> #include <regex> #include <vector> #include "StudentRep.h" #include "Teacher.h" #include "Admin.h" #include "ReservationRecord.h" #include "MachineRoom.h" using namespace std;class ManageSystem { private : vector<StudentRep> v_sr; vector<Teacher> v_t ; vector<Admin> v_a; vector<MachineRoom> v_mr; ReservationRecord* resRec; public : ManageSystem (); ~ManageSystem (); void LoadFile (int type) ; void StartMenu () ; bool CinJudgement (string s1, int type) ; void Login (int choice) ; void MachineRoomUpdate () ; void ChildMenu (Base* person, int type) ; void Exit () ; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 #include "ManageSystem.h" void ManageSystem::LoadFile (int type) { ifstream ifs; switch (type) { case 1 : if (!this ->v_sr.empty ()) this ->v_sr.clear (); ifs.open (STU_PATH, ios::in); if (ifs.is_open ()) { int fId; string fName, fPasswd; while (ifs >> fId && ifs >> fName && ifs >> fPasswd) { this ->v_sr.push_back (StudentRep (fId, fName, fPasswd)); } } ifs.close (); break ; case 2 : if (!this ->v_t .empty ()) this ->v_t .clear (); ifs.open (TEACHER_PATH, ios::in); if (ifs.is_open ()) { int fId; string fName, fPasswd; while (ifs >> fId && ifs >> fName && ifs >> fPasswd) { this ->v_t .push_back (Teacher (fId, fName, fPasswd)); } } ifs.close (); break ; case 3 : if (!this ->v_a.empty ()) this ->v_a.clear (); ifs.open (ADMIN_PATH, ios::in); if (ifs.is_open ()) { int fId; string fName, fPasswd; while (ifs >> fId && ifs >> fName && ifs >> fPasswd) { this ->v_a.push_back (Admin (fId, fName, fPasswd)); } } ifs.close (); break ; case 4 : ifs.open (MACHINE_PATH, ios::in); if (!ifs.is_open ()) { cout << "机房信息读取失败!" << endl; ifs.close (); return ; } int room = 0 , machineNum = 0 ; while (ifs >> room && ifs >> machineNum) { this ->v_mr.push_back (MachineRoom (room, machineNum)); } ifs.close (); break ; } } ManageSystem::ManageSystem () { this ->LoadFile (1 ); this ->LoadFile (2 ); this ->LoadFile (3 ); this ->LoadFile (4 ); this ->resRec = new ReservationRecord; } ManageSystem::~ManageSystem () { if (!this ->v_sr.empty ()) { this ->v_sr.clear (); } if (!this ->v_t .empty ()) { this ->v_t .clear (); } if (!this ->v_a.empty ()) { this ->v_a.clear (); } this ->v_mr.clear (); if (this ->resRec != NULL ) { delete this ->resRec; this ->resRec = NULL ; } } bool ManageSystem::CinJudgement (string s1, int type) { bool flag = true ; regex r ("\\d{0,3}" ) ; if (type == R_TYPE1) { r = regex ("\\d{0,3}" ); } else if (type == R_TYPE2) { r = regex ("\\d{0,4}" ); } else if (type == R_TYPE3) { r = regex ("\\d{0,9}" ); } while (!(flag = regex_match (s1, r))) { return flag; } return flag; } void ManageSystem::StartMenu () { cout << "======================= 欢迎来到传智播客机预约系统 ==============" << endl; cout << endl << "请输入您的身份" << endl; cout << "\t\t--------------------------------------------\n" ; cout << "\t\t| 1.学生代表 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 2.教 师 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 3.管 理 员 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 0.退 出 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t--------------------------------------------\n" ; cout << "请输入您的选择:" ; } void ManageSystem::Login (int choice) { if (choice == 0 ) { this ->Exit (); return ; } Base* person; ifstream ifs; switch (choice) { case 1 : ifs.open (STU_PATH, ios::in); if (!ifs.is_open ()) { cout << "文件不存在!" << endl; ifs.close (); return ; } break ; case 2 : ifs.open (TEACHER_PATH, ios::in); if (!ifs.is_open ()) { cout << "文件不存在!" << endl; ifs.close (); return ; } break ; case 3 : ifs.open (ADMIN_PATH, ios::in); if (!ifs.is_open ()) { cout << "文件不存在!" << endl; ifs.close (); return ; } break ; } int id = 0 ; string temp; string passwd; string usrType[3 ] = { "学生代表" ,"教师" ,"管理员" }; cout << "请输入您的" << usrType[choice - 1 ] << "账号:" ; cin >> temp; while (!CinJudgement (temp, R_TYPE3)) { cout << "输入错误,请重新输入:" ; cin >> temp; } id = stoi (temp); cout << "请输入您的" << usrType[choice - 1 ] << "密码:" ; cin >> passwd; int fId; string fName, fPasswd; switch (choice) { case 1 : while (ifs >> fId && ifs >> fName && ifs >> fPasswd) { if (id == fId && passwd == fPasswd) { system ("cls" ); cout << "登录成功!" << endl; cout << fName << ",欢迎您!" << endl; person = new StudentRep (fId, fName, fPasswd); this ->ChildMenu (person, 1 ); return ; } } break ; case 2 : while (ifs >> fId && ifs >> fName && ifs >> fPasswd) { if (id == fId && passwd == fPasswd) { system ("cls" ); cout << "登录成功!" << endl; cout << fName << ",欢迎您!" << endl; person = new Teacher (fId, fName, fPasswd); this ->ChildMenu (person, 2 ); return ; } } break ; case 3 : while (ifs >> fId && ifs >> fName && ifs >> fPasswd) { if (id == fId && passwd == fPasswd) { system ("cls" ); cout << "登录成功!" << endl; cout << fName << ",欢迎您!" << endl; person = new Admin (fId, fName, fPasswd); this ->ChildMenu (person, 3 ); return ; } } break ; } cout << "验证错误,登录失败!" << endl; system ("pause" ); system ("cls" ); } void ManageSystem::MachineRoomUpdate () { ofstream ofs; ofs.open (MACHINE_PATH, ios::out | ios::trunc); for (vector<MachineRoom>::iterator it = this ->v_mr.begin (); it != this ->v_mr.end (); it++) { ofs << it->roomNum << " " << it->machineNum << endl; } ofs.close (); } void ManageSystem::ChildMenu (Base* person, int type) { if (type == 1 ) { StudentRep* studentRep = (StudentRep*)person; while (true ) { int choice = studentRep->System (); switch (choice) { case 0 : if (studentRep->Logout ()) { return ; } break ; case 1 : studentRep->applyReservation (this ->v_mr, *(this ->resRec)); break ; case 2 : studentRep->showMyReservation (*(this ->resRec)); system ("pause" ); system ("cls" ); break ; case 3 : studentRep->showAllReservation (*(this ->resRec)); break ; case 4 : studentRep->cancelReservation (this ->v_mr, *(this ->resRec)); this ->MachineRoomUpdate (); break ; } } } else if (type == 2 ) { Teacher* teacher = (Teacher*)person; while (true ) { int choice = teacher->System (); bool pass = false ; switch (choice) { case 0 : if (teacher->Logout ()) { return ; } break ; case 1 : teacher->showAllReservation (*(this ->resRec)); break ; case 2 : pass = teacher->auditReservation (this ->v_mr, *(this ->resRec)); if (pass) this ->MachineRoomUpdate (); break ; } } } else if (type == 3 ) { Admin* admin = (Admin*)person; while (true ) { int choice = admin->System (); int type = 0 ; switch (choice) { case 0 : if (admin->Logout ()) { return ; } break ; case 1 : type = admin->addAccount (this ->v_sr, this ->v_t , this ->v_a); this ->LoadFile (type); break ; case 2 : admin->showAccount (this ->v_sr, this ->v_t , this ->v_a); break ; case 3 : admin->showMachine (); break ; case 4 : admin->clearReservation (this ->v_mr); this ->MachineRoomUpdate (); this ->resRec->LoadFile (); break ; } } } } void ManageSystem::Exit () { cout << "您确定要退出吗?[Y/N]:" ; char choice; cin >> choice; if (choice == 'Y' || choice == 'y' ) { cout << "欢迎再次使用本系统" << endl; exit (0 ); } cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); system ("pause" ); system ("cls" ); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #pragma once #include <iostream> #include <string> #include <fstream> #include <regex> #include <map> #include "globalDefine.h" using namespace std;class Base { public : int m_Id; string m_Name; string m_Passwd; virtual void openMenu () = 0 ; virtual int System () = 0 ; virtual bool Logout () = 0 ; bool CinJudgement (string s1, int type) ; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include "Base.h" bool Base::CinJudgement (string s1, int type) { bool flag = true ; regex r ("\\d{0,3}" ) ; switch (type) { case 1 : r = regex ("\\d{0,3}" ); break ; case 2 : r = regex ("\\d{0,4}" ); break ; case 3 : r = regex ("\\d{0,9}" ); break ; case 4 : r = regex ("\\d{0,2}" ); break ; } while (!(flag = regex_match (s1, r))) { return flag; } return flag; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #pragma once #include <iostream> #include "Base.h" #include "ReservationRecord.h" #include "MachineRoom.h" using namespace std;class StudentRep : public Base{ public : StudentRep (int id, string name, string passwd); int System () ; void openMenu () ; void applyReservation (vector<MachineRoom>& v_mr, ReservationRecord& resRec) ; void showMyReservation (ReservationRecord& resRec) ; void showAllReservation (ReservationRecord& resRec) ; void cancelReservation (vector<MachineRoom>& v_mr, ReservationRecord& resRec) ; bool Logout () ; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 #include "StudentRep.h" StudentRep::StudentRep (int id, string name, string passwd) { this ->m_Id = id; this ->m_Name = name; this ->m_Passwd = passwd; } int StudentRep::System () { this ->openMenu (); string temp; cin >> temp; while (!CinJudgement (temp, R_TYPE2)) { cout << "输入错误,请重新输入:" ; cin >> temp; } int choice = stoi (temp); if (choice > 9 ) { choice %= 10 ; } return choice; } void StudentRep::openMenu () { cout << "学生代表操作系统:" << endl; cout << "\t\t--------------------------------------------\n" ; cout << "\t\t| 1.申请预约 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 2.查看我的预约 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 3.查看所有预约 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 4.取消预约 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 0.注销登录 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t--------------------------------------------\n" ; cout << "请输入您的选择:" ; } void StudentRep::applyReservation (vector<MachineRoom> &v_mr, ReservationRecord& resRec) { cout << "机房开放时间为周一至周五:" << endl; cout << "1、周一\t2、周二\t3、周三\t4、周四\t5、周五" << endl; cout << "请选择预约的时间:" ; int date = 0 ; while (true ) { char choice; cin >> choice; switch (choice) { case '1' : date = 1 ; break ; case '2' : date = 2 ; break ; case '3' : date = 3 ; break ; case '4' : date = 4 ; break ; case '5' : date = 5 ; break ; default : cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "输入错误,请重新输入:" ; continue ; } break ; } cout << endl; cout << "请选择申请预约的时间段:" << endl; cout << "1、上午\t2、下午:" ; int time = 0 ; while (true ) { char choice; cin >> choice; if (choice == '1' ) { time = 1 ; break ; } else if (choice == '2' ) { time = 2 ; break ; } cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "输入错误,请重新输入:" ; } cout << endl; cout << "1号机房剩余机器:" << v_mr[0 ].machineNum << endl; cout << "2号机房剩余机器:" << v_mr[1 ].machineNum << endl; cout << "3号机房剩余机器:" << v_mr[2 ].machineNum << endl; cout << "请选择机房:" ; int room = 0 ; while (true ) { char choice; cin >> choice; if (choice == '1' ) { room = 1 ; break ; } else if (choice == '2' ) { room = 2 ; break ; } else if (choice == '3' ) { room = 2 ; break ; } cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "输入错误,请重新输入:" ; } if (v_mr[room].machineNum < 1 ) { cout << "机房已满,预约失败!" << endl; return ; } ofstream ofs; ofs.open (RESERVATION_PATH, ios::app); ofs << "date:" << date << " " ; ofs << "time:" << time << " " ; ofs << "stuId:" << this ->m_Id << " " ; ofs << "stuName:" << this ->m_Name << " " ; ofs << "roomId:" << room << " " ; ofs << "status:" << STATUS_ING << endl; ofs.close (); resRec.LoadFile (); cout << "申请预约成功!" << endl; system ("pause" ); system ("cls" ); } void StudentRep::showMyReservation (ReservationRecord& resRec) { for (map<int , map<string, string>>::iterator it = resRec.resRec.begin (); it != resRec.resRec.end (); it++) { if (stoi (it->second["stuId" ]) == this ->m_Id) { cout << "日期:" ; switch (stoi (it->second["date" ])) { case 1 : cout << "周一 " ; break ; case 2 : cout << "周二 " ; break ; case 3 : cout << "周三 " ; break ; case 4 : cout << "周四 " ; break ; case 5 : cout << "周五 " ; break ; } cout << "时间段:" ; switch (stoi (it->second["time" ])) { case 1 : cout << "上午 " ; break ; case 2 : cout << "下午 " ; break ; } cout << "学生账号:" << it->second["stuId" ] << " " ; cout << "学生姓名:" << it->second["stuName" ] << " " ; cout << "房间号:" << it->second["roomId" ] << " " ; cout << "审核状态:" ; switch (stoi (it->second["status" ])) { case STATUS_ING: cout << "审核中" << endl; break ; case STATUS_PASS: cout << "审核通过" << endl; break ; case STATUS_FAIL: cout << "审核未通过" << endl; break ; } } } } void StudentRep::showAllReservation (ReservationRecord& resRec) { for (map<int , map<string, string>>::iterator it = resRec.resRec.begin (); it != resRec.resRec.end (); it++) { cout << "日期:" ; switch (stoi (it->second["date" ])) { case 1 : cout << "周一 " ; break ; case 2 : cout << "周二 " ; break ; case 3 : cout << "周三 " ; break ; case 4 : cout << "周四 " ; break ; case 5 : cout << "周五 " ; break ; } cout << "时间段:" ; switch (stoi (it->second["time" ])) { case 1 : cout << "上午 " ; break ; case 2 : cout << "下午 " ; break ; } cout << "学生账号:" << it->second["stuId" ] << " " ; cout << "学生姓名:" << it->second["stuName" ] << " " ; cout << "房间号:" << it->second["roomId" ] << " " ; cout << "审核状态:" ; switch (stoi (it->second["status" ])) { case STATUS_ING: cout << "审核中" << endl; break ; case STATUS_PASS: cout << "审核通过" << endl; break ; case STATUS_FAIL: cout << "审核未通过" << endl; break ; } } system ("pause" ); system ("cls" ); } void StudentRep::cancelReservation (vector<MachineRoom>& v_mr, ReservationRecord& resRec) { this ->showMyReservation (resRec); cout << "请选择你要取消的预约(输入记录序号):" ; string temp; cin >> temp; while (!CinJudgement (temp, R_TYPE3)) { cout << "输入错误,请重新输入:" ; cin >> temp; } int index = stoi (temp); int count = 0 ; bool findFlag = false ; map<int , map<string, string>>::iterator it; for (it = resRec.resRec.begin (); it != resRec.resRec.end (); it++) { if (stoi (it->second["stuId" ]) == this ->m_Id) { count++; if (index == count) { findFlag = true ; break ; } } } if (findFlag) { if (stoi (it->second["status" ]) == STATUS_PASS) { switch (stoi (it->second["roomId" ])) { case 1 : v_mr[0 ].machineNum++; break ; case 2 : v_mr[1 ].machineNum++; break ; case 3 : v_mr[2 ].machineNum++; break ; } } resRec.resRec.erase (it); resRec.m_Size--; resRec.update (); cout << "取消成功!" << endl; } else { cout << "记录未找到" << endl; } system ("pause" ); system ("cls" ); } bool StudentRep::Logout () { cout << "您确定要注销登录吗?[Y/N]:" ; char choice; cin >> choice; if (choice == 'Y' || choice == 'y' ) { cout << "注销成功!" << endl; system ("pause" ); system ("cls" ); return true ; } cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "取消登出" << endl; system ("pause" ); system ("cls" ); return false ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #pragma once #include <iostream> #include "Base.h" #include "MachineRoom.h" #include "ReservationRecord.h" using namespace std;class Teacher : public Base{ public : Teacher (int id, string name, string passwd); int System () ; void openMenu () ; void showAllReservation (ReservationRecord& resRec) ; bool auditReservation (vector<MachineRoom>& v_mr, ReservationRecord& resRec) ; bool Logout () ; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 #include "Teacher.h" Teacher::Teacher (int id, string name, string passwd) { this ->m_Id = id; this ->m_Name = name; this ->m_Passwd = passwd; } int Teacher::System () { this ->openMenu (); string temp; cin >> temp; while (!CinJudgement (temp, R_TYPE4)) { cout << "输入错误,请重新输入:" ; cin >> temp; } int choice = stoi (temp); if (choice > 9 ) { choice %= 10 ; } return choice; } void Teacher::openMenu () { cout << "教师操作系统:" << endl; cout << "\t\t--------------------------------------------\n" ; cout << "\t\t| 1.查看所有预约 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 2.审核预约 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 0.注销登录 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t--------------------------------------------\n" ; cout << "请输入您的选择:" ; } void Teacher::showAllReservation (ReservationRecord& resRec) { for (map<int , map<string, string>>::iterator it = resRec.resRec.begin (); it != resRec.resRec.end (); it++) { cout << "日期:" ; switch (stoi (it->second["date" ])) { case 1 : cout << "周一 " ; break ; case 2 : cout << "周二 " ; break ; case 3 : cout << "周三 " ; break ; case 4 : cout << "周四 " ; break ; case 5 : cout << "周五 " ; break ; } cout << "时间段:" ; switch (stoi (it->second["time" ])) { case 1 : cout << "上午 " ; break ; case 2 : cout << "下午 " ; break ; } cout << "学生账号:" << it->second["stuId" ] << " " ; cout << "学生姓名:" << it->second["stuName" ] << " " ; cout << "房间号:" << it->second["roomId" ] << " " ; cout << "审核状态:" ; switch (stoi (it->second["status" ])) { case STATUS_ING: cout << "审核中" << endl; break ; case STATUS_PASS: cout << "审核通过" << endl; break ; case STATUS_FAIL: cout << "审核未通过" << endl; break ; } } system ("pause" ); system ("cls" ); } bool Teacher::auditReservation (vector<MachineRoom>& v_mr, ReservationRecord& resRec) { for (map<int , map<string, string>>::iterator it = resRec.resRec.begin (); it != resRec.resRec.end (); it++) { if (stoi (it->second["status" ]) == STATUS_ING) { cout << "日期:" ; switch (stoi (it->second["date" ])) { case 1 : cout << "周一 " ; break ; case 2 : cout << "周二 " ; break ; case 3 : cout << "周三 " ; break ; case 4 : cout << "周四 " ; break ; case 5 : cout << "周五 " ; break ; } cout << "时间段:" ; switch (stoi (it->second["time" ])) { case 1 : cout << "上午 " ; break ; case 2 : cout << "下午 " ; break ; } cout << "学生账号:" << it->second["stuId" ] << " " ; cout << "学生姓名:" << it->second["stuName" ] << " " ; cout << "房间号:" << it->second["roomId" ] << " " ; cout << "审核状态:审核中" << endl; } } cout << "请输入你要审核的预约信息(输入记录序号):" ; string temp; cin >> temp; while (!CinJudgement (temp, R_TYPE3)) { cout << "输入错误,请重新输入:" ; cin >> temp; } int index = stoi (temp); int count = 0 ; bool findFlag = false ; map<int , map<string, string>>::iterator it; for (it = resRec.resRec.begin (); it != resRec.resRec.end (); it++) { if (stoi (it->second["status" ]) == STATUS_ING) { count++; if (index == count) { findFlag = true ; break ; } } } if (findFlag) { while (true ) { cout << "请输入审核是否通过(Y/N):" ; char choice; cin >> choice; if (choice == 'Y' || choice == 'y' ) { it->second["status" ] = "2" ; cout << "审核完成" << endl; switch (stoi (it->second["roomId" ])) { case 1 : v_mr[0 ].machineNum--; break ; case 2 : v_mr[1 ].machineNum--; break ; case 3 : v_mr[2 ].machineNum--; break ; } cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); resRec.update (); system ("pause" ); system ("cls" ); return true ; } else if (choice == 'n' || choice == 'N' ) { it->second["status" ] = "3" ; cout << "审核完成" << endl; cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); resRec.update (); system ("pause" ); system ("cls" ); return false ; } cout << "输入错误,请重新输入" << endl; cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); } } else cout << "记录未找到!" << endl; system ("pause" ); system ("cls" ); return false ; } bool Teacher::Logout () { cout << "您确定要注销登录吗?[Y/N]:" ; char choice; cin >> choice; if (choice == 'Y' || choice == 'y' ) { cout << "注销成功!" << endl; system ("pause" ); system ("cls" ); return true ; } cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "取消登出" << endl; system ("pause" ); system ("cls" ); return false ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #pragma once #include <iostream> #include "Base.h" #include "Teacher.h" #include "StudentRep.h" using namespace std;class Admin : public Base{ public : Admin (int id, string name, string passwd); int System () ; void openMenu () ; int addAccount (vector<StudentRep>& v_sr, vector<Teacher>& v_t , vector<Admin>& v_a) ; void showAccount (vector<StudentRep>& v_sr, vector<Teacher>& v_t , vector<Admin>& v_a) ; void showMachine () ; void clearReservation (vector<MachineRoom>& v_mr) ; bool Logout () ; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 #include "Admin.h" Admin::Admin (int id, string name, string passwd) { this ->m_Id = id; this ->m_Name = name; this ->m_Passwd = passwd; } int Admin::System () { this ->openMenu (); string temp; cin >> temp; while (!CinJudgement (temp, R_TYPE2)) { cout << "输入错误,请重新输入:" ; cin >> temp; } int choice = stoi (temp); if (choice > 9 ) { choice %= 10 ; } return choice; } void Admin::openMenu () { cout << "管理员操作系统:" << endl; cout << "\t\t--------------------------------------------\n" ; cout << "\t\t| 1.添加账号 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 2.查看账号 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 3.查看机房 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 4.清空预约 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t| 0.注销登录 |\n" ; cout << "\t\t| |\n" ; cout << "\t\t--------------------------------------------\n" ; cout << "请输入您的选择:" ; } void SaveAccountData (string fileName, Base* person) { ofstream ofs; ofs.open (fileName, ios::out | ios::app); if (!ofs.is_open ()) { cout << "Saving fail" << endl; ofs.close (); return ; } ofs << person->m_Id << " " << person->m_Name << " " << person->m_Passwd << endl; ofs.close (); cout << "添加成功!" << endl; } int Admin::addAccount (vector<StudentRep>& v_sr, vector<Teacher>& v_t , vector<Admin>& v_a) { int id = -1 ; string name, passwd; system ("cls" ); cout << "-------------------------" << endl; cout << "1.添加学生代表账号" << endl; cout << "2.添加教师账号" << endl; cout << "3.添加管理员账号" << endl; cout << "0.取消添加" << endl; cout << "请输入您的选择:" ; string temp; cin >> temp; while (!CinJudgement (temp, R_TYPE1)) { cout << "输入错误,请重新输入:" ; cin >> temp; } int choice = stoi (temp); if (choice == 0 ) { system ("cls" ); return 0 ; } string usrType[3 ] = { "学生代表" ,"教师" ,"管理员" }; cout << "请输入" << usrType[choice -1 ] << "账号:" ; cin >> temp; while (!CinJudgement (temp, R_TYPE3)) { cout << "输入错误,请重新输入:" ; cin >> temp; } id = stoi (temp); switch (choice) { case 1 : for (vector<StudentRep>::iterator it = v_sr.begin (); it != v_sr.end (); it++) { if (id == it->m_Id) { cout << "账号已存在,创建失败!" << endl; system ("pause" ); system ("cls" ); return 0 ; } } break ; case 2 : for (vector<Teacher>::iterator it = v_t .begin (); it != v_t .end (); it++) { if (id == it->m_Id) { cout << "账号已存在,创建失败!" << endl; system ("pause" ); system ("cls" ); return 0 ; } } break ; case 3 : for (vector<Admin>::iterator it = v_a.begin (); it != v_a.end (); it++) { if (id == it->m_Id) { cout << "账号已存在,创建失败!" << endl; system ("pause" ); system ("cls" ); return 0 ; } } break ; } cout << "请输入" << usrType[choice - 1 ] << "姓名:" ; cin >> name; cout << "请输入" << usrType[choice - 1 ] << "密码:" ; cin >> passwd; Base* person = NULL ; switch (choice) { case 1 : person = new StudentRep (id, name, passwd); SaveAccountData (STU_PATH, person); break ; case 2 : person = new Teacher (id, name, passwd); SaveAccountData (TEACHER_PATH, person); break ; case 3 : person = new Admin (id, name, passwd); SaveAccountData (ADMIN_PATH, person); break ; } delete person; person = NULL ; system ("pause" ); system ("cls" ); return choice; } void Admin::showAccount (vector<StudentRep> &v_sr, vector<Teacher>& v_t , vector<Admin>& v_a) { system ("cls" ); cout << "学生代表信息:" << endl; for (vector<StudentRep>::iterator it = v_sr.begin (); it != v_sr.end (); it++) { cout << "账号:" << it->m_Id << "\t姓名:" << it->m_Name << "\t密码:" << it->m_Passwd << endl; } cout << "\n教师信息:" << endl; for (vector<Teacher>::iterator it = v_t .begin (); it != v_t .end (); it++) { cout << "账号:" << it->m_Id << "\t姓名:" << it->m_Name << "\t密码:" << it->m_Passwd << endl; } cout << "\n管理员信息:" << endl; for (vector<Admin>::iterator it = v_a.begin (); it != v_a.end (); it++) { cout << "账号:" << it->m_Id << "\t姓名:" << it->m_Name << endl; } system ("pause" ); system ("cls" ); } void Admin::showMachine () { ifstream ifs; ifs.open (MACHINE_PATH, ios::in); if (!ifs.is_open ()) { cout << "File open failed" << endl; ifs.close (); return ; } int roomNum = 0 , machineNum = 0 ; while (ifs >> roomNum && ifs >> machineNum) { cout << roomNum << "号机房机器数:" << machineNum << endl; } ifs.close (); system ("pause" ); system ("cls" ); } void Admin::clearReservation (vector<MachineRoom> &v_mr) { cout << "您确定要清空预约吗?[Y/N]:" ; char choice; cin >> choice; if (choice == 'Y' || choice == 'y' ) { ofstream ofs; ofs.open (RESERVATION_PATH, ios::trunc); ofs.close (); v_mr[0 ].machineNum = 20 ; v_mr[1 ].machineNum = 50 ; v_mr[2 ].machineNum = 100 ; cout << "清空成功!" << endl; system ("pause" ); system ("cls" ); return ; } cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "取消清空" << endl; system ("pause" ); system ("cls" ); } bool Admin::Logout () { cout << "您确定要注销登录吗?[Y/N]:" ; char choice; cin >> choice; if (choice == 'Y' || choice == 'y' ) { cout << "注销成功!" << endl; system ("pause" ); system ("cls" ); return true ; } cin.ignore (numeric_limits<std::streamsize>::max (), '\n' ); cout << "取消登出" << endl; system ("pause" ); system ("cls" ); return false ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #pragma once #include <iostream> #include <fstream> #include <map> #include "globalDefine.h" using namespace std;class MachineRoom { public : int roomNum; int machineNum; MachineRoom (int room, int machineNum); };
1 2 3 4 5 6 7 #include "MachineRoom.h" MachineRoom::MachineRoom (int room, int machineNum) { this ->roomNum = room; this ->machineNum = machineNum; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #pragma once #include <iostream> #include <string> #include <fstream> #include <map> #include "globalDefine.h" using namespace std;class ReservationRecord { public : int m_Size; ReservationRecord (); ~ReservationRecord (); void LoadFile () ; void update () ; map<int , map<string, string>> resRec; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 #include "ReservationRecord.h" void divide (map<string, string>& m, string data) { string key, value; int pos = data.find (":" ); if (pos != -1 ) { key = data.substr (0 , pos); value = data.substr (pos + 1 , data.size () - pos - 1 ); m.insert (pair <string, string>(key, value)); } } void ReservationRecord::LoadFile () { this ->m_Size = 0 ; string date; string time; string stuId; string stuName; string roomId; string status; ifstream ifs; ifs.open (RESERVATION_PATH, ios::in); if (!ifs.is_open ()) { cout << "file open failed" << endl; ifs.close (); return ; } if (!this ->resRec.empty ()) { this ->resRec.clear (); } while (ifs >> date && ifs >> time && ifs >> stuId && ifs >> stuName && ifs >> roomId && ifs >> status) { map<string, string> m; divide (m, date); divide (m, time); divide (m, stuId); divide (m, stuName); divide (m, roomId); divide (m, status); this ->m_Size++; this ->resRec.insert (make_pair (this ->m_Size, m)); } ifs.close (); } ReservationRecord::ReservationRecord () { this ->LoadFile (); } ReservationRecord::~ReservationRecord () { if (!this ->resRec.empty ()) { this ->resRec.clear (); } } void ReservationRecord::update () { ofstream ofs; if (this ->m_Size == 0 ) { ofs.open (RESERVATION_PATH, ios::out | ios::trunc); ofs.close (); return ; } ofs.open (RESERVATION_PATH, ios::out | ios::trunc); for (map<int , map<string, string>>::iterator it = this ->resRec.begin (); it != this ->resRec.end ();it++) { ofs << "date:" << it->second["date" ] << " " ; ofs << "time:" << it->second["time" ] << " " ; ofs << "stuId:" << it->second["stuId" ] << " " ; ofs << "stuName:" << it->second["stuName" ] << " " ; ofs << "roomId:" << it->second["roomId" ] << " " ; ofs << "status:" << it->second["status" ] << endl; } ofs.close (); this ->LoadFile (); }