第三章标准库类型
Library Types
3.1 Namespace
为什么要用namespace?
namespace就是为了区分重名的类。
名字空间的主要作用是解决标识符冲突问题。
比如C++ Standard Library就是在名字空间std下,如果没有名字空间,其中的list就非常可能和自己定义的一些标识符重复。
两种使用方法:
1、 std::list<int> myIntList;
2、在cpp文件的开头加上using namespace std;
这样在文件中就可以直接使用list<int> myIntList了。
3.2 string
初始化:
string s1;
string s2(s1);
string s3("value");
string s4(n, 'c');
|
读入string对象,有两种方式
1. 使用读入操作符cin
2. 使用getline()函数
输入操作符会忽略开头的空格,直至遇到第一个空白字符(leading space)就停止读入。和输入操作符不一样的是,getline() 并不忽略行开头的换行符。
String.size()返回的不是int或者unsigned数据类型,而是一个和机器无关的string::size_type,虽然不知道string::size_type的具体类型,但可以肯定的是它一定是unsigned类型。
string st1, st2 = "The expense of spirit";
st1 = st2; // 这是两个对象,replace st1 by a copy of st2
|
更加关键的是st1 = st2;的执行过程:
1实际上是把原来分配给st1的空间删除掉,
2再分配新的空间,copy过来st2的内容。
3.3 vector
vector中包含的必须是统一的数据类型。
vector不是一种类型,这是一个模板template。
vector并不需要预先分配内存空间。
初始化:
vector<T> v1;
vector<T> v2(v1);
vector<T> v3(n, i);
vector<T> v4(n);
|
vector的大小
vector<int> ivec(10,1);
vector<int>::size_type size = ivec.size();
|
tip:
如果要取得vector的大小,要定义数据类型是vector<int>::size_type。这和Java有很大的不同,随意性很小了。
3.4 Introducing Iterators
每个容器类型都会定义自己的迭代类型。
vector<int>对应的迭代类型就是vector<int>::iterator。
每个容器类型中都会包含一个成员(member),这个成员是容器的迭代器的实际类型。
只要一种类型实现了迭代器所定义的所有操作,那么这种类型就可以称为是一个迭代器类型(iterator type)。因此迭代器类型有很多种。
每种容器类型都定义了对应的iterator类型,但是并不是所有的容器类型都定义下表索引的方式。因此应使用容器访问容器的单元。
访问当前单元的值要使用解引用操作符*,解引用操作符返回的是一个值。
for (vector<int>::iterator iter = ivec.begin();
iter != ivec.end(); ++iter)
*iter = 0; //set element to which iter refers to 0
|
const_iterator
我刚开始不是很明白为什么要定义const_iterator类型,后来看了下面的代码 – 以只读模式遍历一个vector,就明白了
定义:const vector<int>::iterator it
遍历:++it;
|
遍历:++it //错误!
所以要这样定义:
vector<int>::const_iterator it
遍历:++it // ok
// an iterator that cannot write elements
vector<int>::const_iterator
// an iterator whose value cannot change
const vector<int>::iterator
|
任何操作改变了vector的size,那么现有的iterator都会失效。就是说,
先执行vector<int>::iterator iter = ivec.begin()
然后追加element:ivec.add(9);
那么前面的iter就失效了。
3.5 bitset
首先明确这和vector一样,都是模板template。bitset只有大小的不同。
bitset<32> bitvec; // 32 bits, all zero
bitset初始化
bitset<n> b;
bitset<n> b(u);
bitset<n> b(s);
bitset<n> b(s, pos, n); //b 是 string 对象 s中含有的位串的副本,从pos位置截取n个bit
|
从构造函数可以看出,bitset是指定长度的,这和vector有点不一样。
从string初始化bitset,要注意的是string和bitset的顺序是相反的:就是说从右向左读string的bit。
例如:
string strval("1100");
bitset<32> bitvec4(strval);
|
那么bitvec4的第2位,第3位才是1.即使是对string的截串处理也应保证从右向左读。