Skip to content

Commit fd9a62b

Browse files
committed
c++ STL
1 parent 21a283f commit fd9a62b

23 files changed

+12723
-71
lines changed
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include <iostream>
2+
3+
using namespace std;
4+
#define DESC "这是一个类模板的demo ..."
5+
6+
template <class NameType, class AgeType = int>
7+
class Person {
8+
public:
9+
Person(NameType name, AgeType age) {
10+
this->m_Name = name;
11+
this->m_Age = age;
12+
}
13+
void showPerson() {
14+
cout << "name: " << this->m_Name << " 年龄: " << this->m_Age << endl;
15+
}
16+
//姓名
17+
NameType m_Name;
18+
//年龄
19+
AgeType m_Age;
20+
};
21+
void test01() {
22+
Person<string, int> p("孙悟空", 1000);
23+
p.showPerson();
24+
}
25+
void test02() {
26+
Person<string> p("猪八戒", 1000);
27+
p.showPerson();
28+
}
29+
30+
int main() {
31+
// test01();
32+
test02();
33+
return 0;
34+
}

000_1_14-模板template/ctf.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
#include "./ctf.h"
3+
4+
//类外实现
5+
template <class T1, class T2>
6+
void printPerson2(Person<T1, T2> p) {
7+
cout << "printPerson2"
8+
<< " Name:" << p.m_Name << " Age:" << p.m_Age << endl;
9+
};
10+
11+
//通过全局函数 打印Person信息
12+
template <class T1, class T2>
13+
class Person {
14+
friend void printPerson1(Person<T1, T2> p) {
15+
cout << "printPerson1"
16+
<< " Name:" << p.m_Name << " Age:" << p.m_Age << endl;
17+
};
18+
//全局函数 类外实现
19+
//加空模板参数列表
20+
//如果全局函数是类外实现,需要让编译器提前知道这个函数的存在
21+
friend void printPerson2<>(Person<T1, T2> p);
22+
23+
public:
24+
Person(T1 name, T2 age) {
25+
this->m_Name = name;
26+
this->m_Age = age;
27+
}
28+
29+
private:
30+
T1 m_Name;
31+
T2 m_Age;
32+
};
33+
34+
// 1、全局函数在类内实现
35+
void test01() {
36+
Person<string, int> p("Tom", 20);
37+
printPerson1(p);
38+
};
39+
// 2、全局函数在类外实现
40+
void test02() {
41+
Person<string, int> p("Jim", 20);
42+
printPerson2(p);
43+
};

000_1_14-模板template/ctf.h

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef CLASS_TEMPLATE_AND_FRIEND
2+
#define CLASS_TEMPLATE_AND_FRIEND
3+
4+
// body
5+
#include <iostream>
6+
#include <string>
7+
8+
using namespace std;
9+
10+
template <class T1, class T2>
11+
class Person;
12+
13+
template <class T1, class T2>
14+
void printPerson1(Person<T1, T2> p);
15+
16+
template <class T1, class T2>
17+
void printPerson2(Person<T1, T2> p);
18+
19+
// 1: 全局函数在类内部实现
20+
void test01();
21+
// 2: 全局函数在类内部实现
22+
void test02();
23+
24+
//
25+
#endif
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include <iostream>
2+
3+
using namespace std;
4+
5+
#define DESC "这是一个函数模板的demo ..."
6+
7+
/*
8+
函数模板作用:
9+
建立一个通用函数,其函数返回值类型和形参类型可以不具体指定,用一个虚拟的类型来代表
10+
11+
总结:
12+
函数模板利用关键字 template
13+
使用函数模板有两种方式:自动类型推导、显示指定类型
14+
模板的目的是为了提高复用性,将类型参数化
15+
*/
16+
17+
//普通函数
18+
int myAdd01(int a, int b) {
19+
return a + b;
20+
}
21+
//函数模板
22+
template <class T> //声明一个模板,T是一个通用的数据类型
23+
T myAdd02(T a, T b) {
24+
return a + b;
25+
}
26+
//使用函数模板是,如果用自动类型推导,不会发生自动类型转换,即隐式类型转换
27+
void test01() {
28+
int a = 10;
29+
int b = 20;
30+
char c = 'c';
31+
cout << myAdd01(a, b) << endl;
32+
cout << myAdd01(a, c) << endl; //自动类型推导
33+
cout << myAdd02<int>(a, c) << endl; //显示指定类型
34+
}
35+
36+
void test02() {
37+
int a = 10;
38+
int b = 20;
39+
char c = 'c';
40+
// float d = 3.14;
41+
// float e = 6.89;
42+
cout << myAdd02(a, b) << endl;
43+
// cout << myAdd02(a, c) << endl; // error
44+
cout << myAdd02<int>(a, c) << endl;
45+
}
46+
int main() {
47+
// test01();
48+
test02();
49+
return 0;
50+
}

000_1_14-模板template/func_template.cpp

-25
This file was deleted.

000_1_14-模板template/libstf.so

22.5 KB
Binary file not shown.

000_1_14-模板template/main.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
#include "./ctf.h"
3+
4+
int main() {
5+
test01();
6+
test02();
7+
return 0;
8+
}
9+
10+
/*
11+
12+
1 : 直接编译为可执行文件
13+
g++ main.cpp ctf.cpp -std=c++17 -g -Wall
14+
15+
16+
2 :
17+
先编译为so动态库,再连接
18+
g++ ctf.cpp -fPIC -shared -o libstf.so
19+
20+
动态库的连接,调用动态库
21+
g++ main.cpp -L. -lstf -o main -std=c++17 -g -Wall
22+
23+
24+
3: 编译参数说明
25+
-shared 该选项指定生成动态连接库;
26+
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的;
27+
-L.:表示要连接的库在当前目录中;
28+
-ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称;
29+
LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径;
30+
31+
*/

000_1_14-模板template/readme.md

+23
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,26 @@ template <class type> class class-name{
3535
// 在这里,type 是占位符类型名称,可以在类被实例化的时候进行指定。您可以使用一个逗号分隔的列表来定义多个泛型数据类型;
3636
3737
### 2.2 instance
38+
39+
### 2.3 类模板分文件编写
40+
41+
解决:
42+
43+
解决方式 1:直接包含.cpp 源文件
44+
解决方式 2:将.h 和.cpp 中的内容写到一起,将后缀名改为.hpp 文件(比较多)
45+
46+
## 3: 总结
47+
48+
### 3.1 函数模板作用
49+
50+
建立一个通用函数,其函数返回值类型和形参类型可以不具体指定,用一个虚拟的类型来代表
51+
52+
总结:
53+
函数模板利用关键字 template
54+
使用函数模板有两种方式:自动类型推导、显示指定类型
55+
模板的目的是为了提高复用性,将类型参数化
56+
57+
### 3.2 类模板与函数模板区别
58+
59+
类模板没有自动类型推导的使用方式
60+
类模板在模板参数列表中可以有默认参数

000_2_18-STL/readme.md renamed to 000_2_10-STL/readme.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
- 3: C++ STL 的核心组件:
1212
|**Compontent**|**Description**|**other**|
1313
|:--|:--|:--|
14-
|**容器(Containers)**|容器是用来管理某一类对象的集合。C++提供了各种不同的容器,比如`dequeue`,`list`,`vector`,`map`||
14+
|**容器(Containers)**|容器是用来管理某一类对象的集合。C++提供了各种不同的容器,比如`dequeue`,`list`,`vector`,`map`,`set`||
1515
|**算法(algorithms)**|算法作用于容器。它们提供了对容器的各种操作,包括对容器内容执行初始化,排序,搜索,转换等操作||
1616
|**迭代器(iterators)**|迭代器用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的 subset||
17+
|**仿函数()**|行为类似函数,可以作为算法的某种策略||
18+
|**适配器(adaptor)**|一种用来修饰容器,仿函数,迭代器接口的东西||
19+
|**空间配置器()**|负责空间的配置与管理||
1720

1821
# 2: C++ 标准库
1922

000_2_10-STL/test1-vector.cpp

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include <iostream>
2+
#include <vector>
3+
4+
#include <algorithm> //标准算法头文件
5+
6+
#define DESC "本案例是使用 STL vector操作..."
7+
using namespace std;
8+
9+
// vector容器存放内置数据类型
10+
//打印函数
11+
void myPrint(int val) {
12+
cout << "(3) : " << val << endl;
13+
}
14+
15+
int main() {
16+
cout << DESC << endl;
17+
18+
vector<int> vec;
19+
int i;
20+
21+
cout << "vector size = " << vec.size() << endl; // vector size = 0
22+
23+
// 向vector 添加值
24+
for (i = 0; i < 5; i++) {
25+
vec.push_back(i + 1);
26+
};
27+
28+
cout << "vector size = " << vec.size() << endl; // vector size = 5
29+
30+
//同过迭代器访问容器中的数据
31+
vector<int>::iterator itBegin = vec.begin(); //起始迭代器 指向容器中第一个元素
32+
vector<int>::iterator itEnd = vec.end(); //结束迭代器,指向容器中最后一个元素的下一个位置
33+
//第一种遍历方式
34+
while (itBegin != itEnd) {
35+
cout << "(1): " << *itBegin << endl;
36+
itBegin++;
37+
}
38+
39+
//第二种遍历方式
40+
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
41+
cout << "(2) : " << *it << endl;
42+
}
43+
44+
//第三种遍历方式 利用STL提供遍历算法
45+
for_each(vec.begin(), vec.end(), myPrint);
46+
47+
return 0;
48+
}
49+
50+
/*
51+
52+
关于上面实例中所使用的各种函数,有几点要注意:
53+
54+
push_back( ) 成员函数在向量的末尾插入值,如果有必要会扩展向量的大小。
55+
size( ) 函数显示向量的大小。
56+
begin( ) 函数返回一个指向向量开头的迭代器。
57+
end( ) 函数返回一个指向向量末尾的迭代器。
58+
59+
vector 与普通数组区别:不同之处在与数组是静态空间,而 vector 可以动态扩展;
60+
61+
动态扩展:
62+
并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间;
63+
vector 容器的迭代器是支持随机访问的迭代器
64+
*/

0 commit comments

Comments
 (0)