一、模板
模板:C++的编译期代码生成机制,通过参数化类型实现泛型编程,允许编写与类型无关的通用代码。
模板的特点:

泛型编程和模板机制:
泛型编程:一种以类型参数化为核心的编程范式,通过模板机制编写与具体数据类型无关的通用算法和数据结构,实现代码复用且不牺牲运行时性能。

1、函数模板
函数模板:C++中用于生成重载函数的编译期蓝图,通过参数化类型让同一算法适用于不同数据类型,在调用时根据实参自动推导或显式实例化具体函数版本。
函数模板的语法:


总结:

注意事项:
①自动类型推导,必须推导出一致的数据类型T才可以使用。
cpp
template <typename TYPE>
void my_swap(TYPE &a, TYPE &b)
{
TYPE num;
num = a;
a = b;
b = num;
}
int main()
{
int a = 1;
double c = 3.1;
my_swap(a, c); // ❌ a是int类型,c是double类型,不可以使用模板。
system("pause");
return 0;
}
②模板必须要确定T的数据类型才可以使用。
cpp
template <typename TYPE>
void fun()
{
cout << "fun()函数调用" << endl;
}
int main()
{
fun(); // ❌ TYPE类型未确定,不可以使用模板。
fun<int>(); // ✅ TYPE类型是int,TYPE类型确定了,可以使用模板。
system("pause");
return 0;
}
2、函数模板的案例
案例描述:



3、普通函数和函数模版的区别


如果函数模板的参数是引用,也不会发生隐式转换,因为引用不允许改变它的指向,也就是引用绑定的对象不能变。
总结:
4、普通函数和函数模版的调用规则
调用规则:

(1)普通函数和函数模板都可以实现,优先调用普通函数。

注意⚠️:在普通函数和函数模板都可以实现的时候,如果普通函数只有声明,没有定义,那么调用函数时,并不是调用函数模板,还是按照优先调用普通函数的规则,又因为普通函数没有实现,直接报错误信息。
(2)通过空模板参数列表(<>)可以强制调用函数模板。
(3)函数模板也可以重载。

(4)函数模板可以更好的匹配,优先调用函数模板。

总结:
5、模板的局限性
局限性:模板不是万能的,有些特定的数据类型需要具体化方式进行特殊的实现。


总结:

6、类模板
类模板:一种代码蓝图,允许你定义一个通用类,其中数据类型作为参数,在实例化时再指定具体类型(如 vector<int>)
语法:


总结:
7、类模板与函数模板的区别

(1)类模板不可以自动类型推导

(2)类模板的参数列表可以有默认参数

8、类模板中成员函数的创建时机

类模板成员函数未调用不创建

类模板成员函数调用时创建

9、类模板对象做函数参数
类模板对象传参的方式:
(1)指定传入的类型:直接显示对象的数据类型


(2)参数模板化:对象中的参数变为模板进行传递


(3)整个类模板化:对象类型模板化进行传递


总结:

10、类模板与继承

指定具体的父类模板类型

子类也使用模板


总结:
11、类模板成员函数类外实现


总结:
12、类模板分文件编写
问题:

解决:

(1)直接包含cpp源文件
person.h:

person.cpp:

main.cpp:


(2)声明和实现在同一个文件中,文件名为.hpp
person.hpp:

main.cpp:


总结:
13、类模板与友元

(1)类内实现

(2)类外实现

总结:
14、类模板的案例
案例描述:实现一个通用数组类

案例测试:
My_Array.hpp:

main.cpp:

测试结果:

案例的完整实现:
My_Array.hpp:
cpp
#include "My_Array.hpp"
#include <string>
void print_array(MyArray<int>& arr)
{
for (int i = 0; i < arr.get_array_size(); i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
void test()
{
cout << "---数组类模板测试---" << endl;
// arr1的数组
MyArray<int> arr1(5);
// 尾插
for (int i = 0; i < 5; i++)
{
arr1.Push_Back(i);
}
cout << "arr1的输出:";
print_array(arr1);
// 容量和大小
cout << "arr1的容量:" << arr1.get_array_capacity() << endl;
cout << "arr1的大小:" << arr1.get_array_size() << endl;
// 拷贝构造
MyArray<int> arr2(arr1);
cout << "arr2的输出:";
print_array(arr2);
// 赋值
MyArray<int> arr3(5);
arr3 = arr1;
cout << "arr3的输出:";
print_array(arr3);
// 尾删
arr2.Pop_Back();
cout << "arr2尾删后" << endl;
cout << "arr2的容量:" << arr2.get_array_capacity() << endl;
cout << "arr2的大小:" << arr2.get_array_size() << endl;
cout << "arr2的输出:";
print_array(arr2);
}
// 自定义数据类型
class Person
{
public:
Person()
{}
Person(string name, int age):m_name(name),m_age(age)
{}
string m_name;
int m_age;
};
void print_person(MyArray<Person> &arr)
{
for (int i = 0; i < arr.get_array_size(); i++)
{
cout << "姓名:" << arr[i].m_name << endl;
cout << "年龄:" << arr[i].m_age << endl;
}
}
void test2()
{
cout << "---自定义数据类型测试---" << endl;
// 数组类模板存储的数据是Person类型
MyArray<Person> arr(5);
Person p1("张三", 20);
Person p2("李四", 22);
Person p3("王五", 25);
Person p4("孙悟空", 18);
Person p5("猪八戒", 21);
// 插入
arr.Push_Back(p1);
arr.Push_Back(p2);
arr.Push_Back(p3);
arr.Push_Back(p4);
arr.Push_Back(p5);
// 输出打印
print_person(arr);
// 修改元素
//Person p6("唐僧", 30);
arr[0] = Person("唐僧", 30);
cout << "arr[0]" << endl;
cout << "姓名:" << arr[0].m_name << endl;
cout << "年龄:" << arr[0].m_age << endl;
// 容量和大小
cout << "arr的容量:" << arr.get_array_capacity() << endl;
cout << "arr的大小:" << arr.get_array_size() << endl;
}
int main()
{
test();
test2();
system("pause");
return 0;
}
main.cpp:
cpp
#include "My_Array.hpp"
#include <string>
void print_array(MyArray<int>& arr)
{
for (int i = 0; i < arr.get_array_size(); i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
void test()
{
cout << "---数组类模板测试---" << endl;
// arr1的数组
MyArray<int> arr1(5);
// 尾插
for (int i = 0; i < 5; i++)
{
arr1.Push_Back(i);
}
cout << "arr1的输出:";
print_array(arr1);
// 容量和大小
cout << "arr1的容量:" << arr1.get_array_capacity() << endl;
cout << "arr1的大小:" << arr1.get_array_size() << endl;
// 拷贝构造
MyArray<int> arr2(arr1);
cout << "arr2的输出:";
print_array(arr2);
// 赋值
MyArray<int> arr3(5);
arr3 = arr1;
cout << "arr3的输出:";
print_array(arr3);
// 尾删
arr2.Pop_Back();
cout << "arr2尾删后" << endl;
cout << "arr2的容量:" << arr2.get_array_capacity() << endl;
cout << "arr2的大小:" << arr2.get_array_size() << endl;
cout << "arr2的输出:";
print_array(arr2);
}
// 自定义数据类型
class Person
{
public:
Person()
{}
Person(string name, int age):m_name(name),m_age(age)
{}
string m_name;
int m_age;
};
void print_person(MyArray<Person> &arr)
{
for (int i = 0; i < arr.get_array_size(); i++)
{
cout << "姓名:" << arr[i].m_name << endl;
cout << "年龄:" << arr[i].m_age << endl;
}
}
void test2()
{
cout << "---自定义数据类型测试---" << endl;
// 数组类模板存储的数据是Person类型
MyArray<Person> arr(5);
Person p1("张三", 20);
Person p2("李四", 22);
Person p3("王五", 25);
Person p4("孙悟空", 18);
Person p5("猪八戒", 21);
// 插入
arr.Push_Back(p1);
arr.Push_Back(p2);
arr.Push_Back(p3);
arr.Push_Back(p4);
arr.Push_Back(p5);
// 输出打印
print_person(arr);
// 修改元素
//Person p6("唐僧", 30);
arr[0] = Person("唐僧", 30);
cout << "arr[0]" << endl;
cout << "姓名:" << arr[0].m_name << endl;
cout << "年龄:" << arr[0].m_age << endl;
// 容量和大小
cout << "arr的容量:" << arr.get_array_capacity() << endl;
cout << "arr的大小:" << arr.get_array_size() << endl;
}
int main()
{
test();
test2();
system("pause");
return 0;
}
结果:

二、STL初识
STL:C++中一套由容器、迭代器、算法和函数对象组成的通用模板库,提供了高效、可复用的数据结构和算法。
STL的诞生:

1、STL的基本概念

STL的六大组件:

STL的容器、算法、迭代器:
(1)容器

(2)算法

(3)迭代器

迭代器的种类:

2、vector
(1)存放内置数据类型



(2)存放自定义数据类型


(3)存放自定义数据类型的指针


3、vector容器嵌套容器


三、STL的常用容器
1、string容器

(1)string构造函数



(2)string赋值操作

①string& operator=(const char *s);

②string& operator=(const string &s);

③string& operator=(char c);

④string& assign(const char *s);

⑤string& assign(const char *s, int n);

⑥string& assign(const string &s);

⑦string& assign(int n, char c);

(3)string字符串拼接

①string& operator+=(const char* str);

②string& operator+=(const char c);

③string& operator+=(const string& str);

④string& append(const char *s);

⑤string& append(const char *s, int n);

⑥string& append(const string &s);

⑦string& append(const string &s, int pos, int n);

(4)string查找和替换

查找:

替换:

(5)string字符串比较
比较方式:字符串比较按照字符的ASCII码对比。(=返回0,>返回1,<返回-1)


(6)string字符存取
string的单个字符存取:


(7)string插入和删除


(8)string子串


2、vector容器
功能:
vector与普通数组的区别:

动态扩展:



(1)vector构造函数


(2)vector赋值操作

①vector& operator=(const vector &vec);

②assign(beg,end);

③assign(n,elem);

(3)vector的容量和大小


resize(指定大小)若指定的更大,默认0填充,重载版本指定填充数值;若指定的更小,多余的删除。
总结:

(4)vector插入和删除


(5)vector数据存取


(6)vector互换容器

①使用示例

②实际用途
巧用swap收缩内存空间

(7)vector预留空间



没有reserve() 预留空间:

reserve() 预留空间:

3、deque容器
功能:
deque和vector的区别:


deque工作原理:


deque容器的迭代器也支持随机访问。
(1)deque构造函数


(2)deque赋值操作

①deque& operator=(const deque &deq);

②assign(beg,end);

③assign(n,elem);

(3)deque大小操作



(4)deque插入和删除



(5)deque数据存取


(6)deque排序操作


4、STL的案例1 - 评委打分
案例描述:

实现步骤:


结果:

5、stack容器
(1)基本概念
stack:先进后出的数据结构,只有一个出口。

栈中只有栈顶元素可被使用,不允许遍历行为。

(2)stack常用接口


总结:

6、queue容器
(1)基本概念
queue:先进先出的数据结构,有两个出口。


(2)queue常用接口



总结:

7、list容器
(1)基本概念

链表和结点




链表的存储方式不是连续的内存空间,因此链表的迭代器只支持前移和后移(只能一个一个递增或递减,不能跳跃几个递增或递减),属于双向迭代器。
优点和缺点


(2)list构造函数


(3)list的赋值和交换


(4)list大小操作


总结:

(5)list插入和删除


总结:

(6)list数据存取


总结:

(7)list反转和排序


总结:

(8)list排序案例



总结:

8、set容器
set容器:所有元素在插入时会自动排序
本质:

(1)set构造和赋值


总结:

(2)set大小和交换


总结:

(3)set插入和删除


总结:

(4)set查找和统计


总结:

(5)set和multiset的区别


总结:

(6)pair对组的创建
功能:

两种创建方式:


(7)set容器排序

①内置类型指定排序规则

②自定义数据类型指定排序规则

总结:

9、map容器
概念:

本质:

优点:

(1)map构造和赋值




(2)map大小和交换



总结:

(3)map插入和删除



总结:

(4)map查找和统计


总结:

(5)map容器排序


总结:

10、STL案例2 - 员工分组
案例描述:

实现步骤:



四、STL函数对象
1、函数对象概念
概念:

本质:

2、函数对象的使用
特点:

(1)函数对象在使用时,像普通函数一样调用,有参数也有返回值。

(2)函数对象超出普通函数的概念,函数对象可以有自己的状态。

(3)函数对象可作为参数传递

3、谓词

(1)一元谓词

(2)二元谓词

4、内建函数对象

(1)算术仿函数




(2)关系仿函数




(3)逻辑仿函数



五、STL常用算法

1、常用遍历算法

(1)for_each



(2)transform



2、常用查找算法

(1)find




(2)find_if

①内置数据类型

②自定义数据类型

(3)adjacent_find




(4)binary_search



无序序列进行binary_search查找,结果未知,所以必须是有序序列才可正确查找。

(5)count


①内置数据类型

②自定义数据类型


(6)count_if


①内置数据类型

②自定义数据类型

3、常用排序算法

(1)sort




(2)random_shuffle




(3)merge




(4)reverse




4、常用拷贝和替换算法

(1)copy




(2)replace




(3)replace_if




(3)swap




5、常用算术生成算法

(1)accumulate




(2)fill




6、常用集合算法

(1)set_intersection




(2)set_union




(3)set_difference




六、演讲比赛流程管理系统
有待解锁。。。
七、机房预约系统
有待解锁。。。

