四、模板初阶
2. 类模板
函数模板就是:模板 + 函数;类模板就是:模板 + 类。和函数模板用法基本相同。类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。
#include<iostream> using namespace std; template<class T> class Stack { public: void push(const T& x) { // } private: T* _a; int _top; int _capacity; }; int main() { Stack<int> s1; Stack<double> s2; return 0; }
声明和定义分离则这样用:
#include<iostream> using namespace std; template<class T> class Stack { public: void push(const T& x); private: T* _a; int _top; int _capacity; }; template<class T> void Stack<T>::push(const T& x) { // } int main() { return 0; }
注意:类模板不能声明和定义分两个文件。(在当前)
五、STL简介
1. 什么是STL
STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。
2. STL的六大组件
3. 如何学习STL
非常简单的一句话:学习STL的三个境界:能够熟用STL;了解泛型编程的内涵;能够拓展STL。
六、string类
- string 是表示字符串的字符串类
- 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作.
- string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
- 不能操作多字节或者变长字符的序列。
在使用string类时,必须包含#include头文件以及using namespace std;
我们来浅尝一下 string 。这是 string 类的构造函数的链接
具体内容可以看上面的链接。我们来实现一下。(其实完全不需要全都掌握,只需要掌握几个常用的即可,其他的偶尔看看文档就行)
#include<iostream> #include<string> using namespace std; void test1() { string s1; string s2("Hello,World!"); string s3(s2); string s4(s2, 5, 3); string s5(s2, 5, 10); string s6(s2, 5); string s7(10, '#'); cout << s1 << endl; cout << s2 << endl; cout << s3 << endl; cout << s4 << endl; cout << s5 << endl; cout << s6 << endl; cout << s7 << endl; } int main() { test1(); return 0; }
结果:
咦?cout 为什么能输出 string类 ?原因库里面已经自动实现了重载流插入和流提取函数,也实现了赋值重载函数。
1. string类对象的容量操作
#include<iostream> #include<string> using namespace std; void test2() { string s1("Hello,World!"); // size函数返回字符串的长度 for (size_t i = 0; i < s1.size(); ++i) { // 重载 s1.operator[](i) 可读可写 cout << s1[i] << ' '; } cout << endl; for (size_t i = 0; i < s1.size(); ++i) { // 可写 ++s1[i]; cout << s1[i] << ' '; } cout << endl; } int main() { test2(); return 0; }
函数重载,多一个带 const 修饰的函数,const 对象则调用这个,使其可读不可写。
string还有一种遍历方法,就是 迭代器(iterator)。
iterator 是一个类型,在类域里面。
#include<iostream> #include<string> using namespace std; void test3() { string s1("Hello,World!"); // iterator是一个类型,在类域里面,需要被类作用域包含 // it是变量名称 // 成员函数begin返回一个iterator(迭代器),指向字符串的起始位置 // 可以省事写成 auto it = s1.begin() string::iterator it = s1.begin(); // end函数和begin一样,只是指向字符串的末尾的下一个地址(因为老美喜欢左闭右开的形式) while (it != s1.end()) { cout << *it << ' '; ++it; } cout << endl; } int main() { test3(); return 0; }
结果:
注意:迭代器是行为像指针的一个类型,但其不一定是指针。
范围for 也能遍历容器,但是范围for在底层还是迭代器。
for (auto e : s1) { // }