目录
模板:
函数模板
类模板
STL简介:
string:
string类对象的常见构造
string类对象的容量操作
string类对象的访问及遍历
模板:
在C语言阶段,当我们需要交换两个int类型的数据就需要写一个支持int类型交换的Swap函数,此函数并不能交换double类型的数据。
现在我们学C++虽然函数模板可以解决,但是,重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数。
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。模板分为函数模板与类模板。
函数模板:
//泛型编程
//模板
//函数模板
template<class T> //template<typename T> //模板参数列表 -- 参数类型
void Swap(T& x1, T& x2) //函数参数列表 -- 参数对象
{
T x = x1;
x1 = x2;
x2 = x;
}
int main()
{
int a = 0, b = 1;
double c = 1.1, d = 2.22;
Swap(a, b);
Swap(c, d);
return 0;
}
函数模板本身不是函数,在使用的时候编译器会推演出相应的函数。在编译器编译阶段,编译器根据传入的实参类型来推演生成对应类型的函数以供 调用。当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然 后产生一份专门处理double类型的代码。
函数模板的实例化:
用不同类型的参数使用函数模板,称为模板实例化,(可以手动实例化)。
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
int main()
{
int a1 = 20, a2 = 30;
double b1 = 10.1, b2 = 10.2;
cout << Add(a1, a2) << endl;
cout << Add(b1, b2) << endl;
//显示实例化
cout << Add<int>(a1, b2) << endl;
cout << Add<double>(a1, b2) << endl;
return 0;
}
当然,不同类型参数也是可以的
template<class T1, class T2>
T2 Add(const T1& left, const T2& right)
{
return left + right;
}
int main()
{
int a1 = 10, a2 = 20;
double d1 = 10.1, d2 = 20.12;
cout << Add(a1, d2) << endl;
return 0;
}
类模板:
当我们用C语言实现栈的时候,我们写一份栈的数据结构,但是如果别的类型想用这个栈,就需要重新实现一份。类模板就很好得解决了这一问题。
//类模板
//Stack 类名
//Stack<T> 类型
template<class T>
class Stack
{
public:
Stack(int capacity = 4)
:_top(0)
, _capacity(capacity);
{
_a = new T[capacity];
}
~Stack()
{
delete[] _a;
_a = nullptr;
_capacity = _top = 0;
}
void Push(const T& x);
private:
T* _a;
int _top;
int _capacity;
};
template<class T>
void Stack<T>::Push(const T& x)
{
//...
}
int main()
{
Stack<int> st1; //存储int
Stack<double> st2;
st1.Push(1);
st1.Push(2);
st1.Push(3);
return 0;
}
我们需要注意的是,单独的Stack是类名,Stack<T>才是类型。
STL简介:
string:
string类对象的常见构造
string() |
构造空的string类对象,即空字符串
|
string(const char* s)
|
用C-string来构造string类对象
|
string(size_t n, char c)
|
string类对象中包含n个字符c
|
string(const string&s)
|
拷贝构造函数
|
//编码 值 符号 建立映射关系 -- 编码表
//ascii编码表 -- 英文
//unicode -- 全世界文字 utf-8 utf-16 utf-31
//gbk -- 中国
//char
//wchar_t
int main()
{
cout << sizeof(char) << endl; //1
cout << sizeof(wchar_t) << endl; //2
return 0;
}
#include <string>
int main()
{
string s1;
string s2("hello world");
string s3(s2);
//cin >> s1;
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
string s4(s2, 2, 6); //从第二个向后拷6个
cout << s4 << endl;
string s5(s2, 2); //从第二个拷到最后
cout << s5 << endl;
string s6(s2, 2, 100); //不全的话也拷到结束
cout << s6 << endl;
string s7("hello world", 3); //拷前3个
cout << s7 << endl;
string s8(10, '!'); //拷10个 !
cout << s8 << endl;
return 0;
}
string类对象的容量操作
size |
返回字符串有效字符长度
|
length |
返回字符串有效字符长度
|
capacity |
返回空间总大小
|
empty |
检测字符串释放为空串,是返回
true
,否则返回
false
|
clear |
清空有效字符
|
reserve |
为字符串预留空间
*
*
|
resize |
将有效字符的个数该成
n
个,多出的空间用字符
c
填充
|
string类对象的访问及遍历
#include<iostream>
using namespace std;
#include<string>
库里面应该是这样的 可读可写
//char& operator[](size_t pos)
//{
// assert(pos < _size);
// return _str[pos];
//}
int main()
{
string s1("hello world");
cout << s1 << endl;
for (size_t i = 0; i < s1.size(); ++i)
{
cout << s1.operator[](i) << " ";
cout << s1[i] << " "; //读
}
cout << endl;
for (size_t i = 0; i < s1.size(); ++i)
{
s1[i] += 1; //写
}
cout << s1 << endl;
for (size_t i = 0; i < s1.size(); ++i)
{
s1.at(i) -= 1; //写
}
cout << s1 << endl;
//s1[100]
try
{
s1.at(100);
}
catch (exception& e)
{
cout << e.what() << endl;
}
return 0;
}
int main()
{
string s1;
s1.push_back('a');
s1.append("bcd");
cout << s1 << endl;
s1 += ':';
s1 += "hello world";
cout << s1 << endl;
return 0;
}