ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

C++的学习第三部分

C++的学习第三部分

一、模板

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

模板的特点:

泛型编程和模板机制:

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

1、函数模板

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

函数模板的语法:

总结:

注意事项:

①自动类型推导,必须推导出一致的数据类型T才可以使用。

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的数据类型才可以使用。

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:

#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:

#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

六、演讲比赛流程管理系统

有待解锁。。。

七、机房预约系统

有待解锁。。。

返回列表