文章目录
- 1.模板
- 2.STL简介
-
- [2.1 STL的版本](#2.1 STL的版本)
- [2.2 STL的六大组件](#2.2 STL的六大组件)
- 3.string(1)
-
- [3.1 C语言中的字符串](#3.1 C语言中的字符串)
- [3.2 string::string](#3.2 string::string)
-
- [1.default (1) `string();`](#1.default (1)
string();
) - [(2).copy (3)substring](#(2).copy (3)substring)
- [(5). from buffer](#(5). from buffer)
- [(6) fill constructor](#(6) fill constructor)
- [1.default (1) `string();`](#1.default (1)
- [3.3 string::operator[]](#3.3 string::operator[])
在模板之前,C语言和C++可能差距感觉不是很大,而模板之后,区别就很大了
1.模板
C++由于函数可以重载,所以有以下函数:
cpp
void Swap(int left, int right)
{
int temp = left;
left = right;
right = temp;
}
void Swap(double left, double right)
{
double temp = left;
left = right;
right = temp;
}
void Swap(float left, float right)
{
float temp = left;
left = right;
right = temp;
}
但是这几个函数相差不大,也就可以用模板写出来:
cpp
template<class T> //也可以用typename来定义
void Swap(T& x, T& y)
{
T temp = x;
x = y;
y = temp;
}
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。 所以其实模板就是将本来应该我们做的重复的事情交给了编译器
cpp
template<class T>
T func(const T& x1, const T& x2)
{
return x1 + x2;
}
int main()
{
int i = 0;
int j = 2;
double m = 1.2;
cout << func(i, j) << endl;
//推导实例化 (通过实参传给形参,推导出结果)
cout << func(i, (int)m) << endl; //1
cout << func((double)i, m) << endl; //1.2
//显示实例化 (显示T可类型到底是什么)
cout << func<int>(i, m) << endl; //1
cout << func<double>(i, m) << endl; //1.2
}
当然也可以定义两个
cpp
template<class T1,class T2>
T1 Add(const T1& x,const T2& y)
{
return x + y;
}
int main()
{
int i = 0;
int j = 2;
double m = 1.2;
cout << Add(i, j) << endl;
//推导实例化 (通过实参传给形参,推导出结果)
cout << Add(i, m) << endl; //1
cout << Add(m, i) << endl; //1.2
}
如果函数的模板同时存在,那么优先调用函数,因为模板需要加工而函数可以直接调用
下面我们用C++来实现栈:
cpp
template<class T>
class Stack
{
public:
Stack(int n = 4)
:_array(new T[n]),
_size(0),
_capacity(n)
{}
~Stack()
{
delete[] _array;
_size = 0;
_capacity = 0;
}
void Push(const T& x);
private:
T* _array;
size_t _capacity;
size_t _size;
};
//申明和定义分离
template<class T>
void Stack<T>::Push(const T& x)//模板要加引用,数据不改变加const,减少拷贝
{
if (_size == _capacity)
{
//扩容
T* tmp = new T[_capacity * 2]; //申请新空间
memcpy(tmp, _array, sizeof(T) * _size);//拷贝原来数据
delete[]_array; //释放旧空间
_array = tmp;
_capacity *= 2;
}
_array[_size] = x;
_size++;
}
那我们在C语言中也可以改typedef来实现放不同类型的数据
但是模板就可以实现同时创建不同类型的栈:
cpp
int main()
{
//类模板都是显示实例化
Stack<int> st1;
st1.Push(1);
st1.Push(1);
st1.Push(1);
st1.Push(1);
Stack<double> st2;
st2.Push(1.1);
st2.Push(1.1);
st2.Push(1.1);
return 0;
}
2.STL简介
由于C语言没有模板所以写出的东西不能通用,而C++可以让模板通过实例化实现函数通用
2.1 STL的版本
- 原始版本
Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许 任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原 始版本一样做开源使用。 HP 版本--所有STL实现版本的始祖。
- P. J. 版本
由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读 性比较低,符号命名比较怪异。
- RW版本
由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一 般。
- SGI版本
由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可 移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。我们后面学习 STL要阅读部分源代码,主要参考的就是这个版本。
2.2 STL的六大组件
空间配置器其实就是一个内存池
3.string(1)
使用时要包含<string>
头文件
3.1 C语言中的字符串
C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列 的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户 自己管理,稍不留神可能还会越界访问。
3.2 string::string
下面是这几个的使用方法:
1.default (1) string();
(2).copy (3)substring
copy (2) | string (const string& str); |
---|---|
substring (3) | string (const string& str, size_t pos, size_t len = npos); |
npos
是静态成员变量
它的值是整形的最大值
(5). from buffer
复制前面n个字符
(6) fill constructor
创建一个由n个字符的字符串
3.3 string::operator[]
其内部实现与下面相似:
cpp
class string
{
public:
char& operator[](size_t _i)
{
assert(_i < _size);
return _str[_i];
}
private:
char* _str;
size_t _size;
size_t capacity;
};
直接返回的是引用,那么我们就可以对字符串的任意位置进行修改了