C++STL标准程序库开发指南笔记

我发现个悲惨的事实,学过的东西,过段时间不用
就还给书本了,真的学了后面的忘记前面的了,记录下
STL的学习笔记吧。
<<C++STL标准程序库开发指南>>中国铁道部出版

第1章
=1.4
类模板 可以用class也可用typename做标识
template <class T>class string{}
template <typename T>class string{}

在模板类外部声明模板类的成员函数时要连模板参数也声明在前头
如:
template <class T>template<class T2>int string<T>::compare(const T2& s)
{
......
}

T是模板类,T2是模板参数。

模板使用规则:
1.成员模板不能为虚(virtue)
2.析构不能是模板类型
3.成员函数模板不能重载基类的虚函数


=1.5 友元模板
友元声明放在类的内部,一般友元成批的放在类的前头或结尾
如
class Screen
{
	friend class Windows;

}
类Windows被声明为类Screen的友元类,之后在类Windows中可以
使用类Screen的非公有资源,包括其私有成员。

(1).非模板函数、类作为实例类的友元
class A
{
	void AF();
};
template <class Type>
class Queue
{
	friend class B;	//类B不需要事先声明
	friend void A();//函数A(),根据上面即A函数能使用Queue的
			//非公有资源也不需要事先声明
	friend void A::AF();//类A必须事先声明
};

(2).模板函数、模板类作为同类型实例类的友元
template  <class Type>class A{...};
template <class Type> void D()(B <Type>);//模板函数
template <class Type> class C{void Cf();...};
template <class Type> class B
{
	friend class A<Type>;//模板类需要事先声明或定义
	friend void D(B <Type>);//模板函数D()必须先声明或定义
	friend void C<Type>::Cf();//模板类C必须先定义
};

没用过,比较难懂。但是没有继承关系,能用别人的东西真不错。

1.6 函数模板
template <class T> void print(T& ii,T&jj){.....}
template <class T1,class T2> void print(T1& ii,T2&jj){.....}
1.7 类模板的参数
template <class Type,int size> class Queue;
可以有默认值,没有指定就按默认值的来
template <class Type=int,int size=1024> class Queue;
这个可以这么实例
Queue<char,100> i;
Queue<int> j;
Queue<> k;

1.7.1
template <class T> class Y
{
	typedef typename T::A TA;
	TA* abc;
	....
}
typename关键字告诉编译器其后的名称为一个类型。没有typename编译不通过

2.1 字符串库简述
string类支持两种输入方式 cin和getline
string stuff;
cin>>stuff;
getline(cin,stuff);//不读入回车换行、
//分界符(可以声明为空格,遇到空格就结束读取)、文件结束符

智能指针auto_ptr帮助管理内存,防止内存泄漏
auto_ptr <double> pd;

double *preg=new double;
pd=p_reg;//不允许
pd=auto_ptr<double>(p_reg);//允许
auto_ptr<double> pauto=p_reg;//不允许 
auto_ptr<double>pauto(p_reg);//允许
总结来就是要用类的构造函数来转换指针

2.4
string::reserve() 保留内存以存储一定数量的字符
不能使用字符或者整数去初始化string
要这么初始化
std::string s("x");
std::string s(1,'x');


2.4.4 字符串的比较
string::compare();很强大,并且能区别字母的大小写

2.4.9 字符串对迭代器的支持
reverse_iterator 反序排列的迭代器


3.1.2 容器的种类和数据结构
STL容器通常分为3种:序列式容器(vector,deque,list,stack),
关联式容器(setmultiset,map,multimap,hashtable),
容器配接器(stack,queue,priority_queue优先级队列)

STL容器的数据结构也包括3种:string字符串,bitset,valarray

3.3序列式容器--vector类模板
#pragma warning(disable:4786)
消除警告信息
定义vector类的对象后,如果没有设置容器的大小,是不允许直接给容器中的元素赋值的
可以用[]和at()

3.3.3vector高级编程
vector<typename T>c
c.at(index);  //返回的是引用,可以取出该值,也可以对元素赋值 index无效会拋出异常
c[index];  //返回的是引用,可以取出该值,
	  //也可以对元素赋值 要确定index有效,无效会错误
c.front();
c.back();

bind2nd(greater<int>(),5);//绑定参数,
因为很多STL的算法都只提供了一个参数,而我们一般要以
某种条件加以参数传给STL的算法,用绑定的方式,
greater<int>是比较类仿函数,这里是大于5


vector<bool>只占用1个bit存储单个元素
vector<bool>类提供了位取反函数flip()

3.4序列式容器--list类模板
(1).list不支持随机存取,不支持[]下标操作,和at() 因为是双向链表
(2).在list的任何位置执行元素的插入和移除都非常快,可以迅速实现。
插入和删除动作不会影响指向其他元素的指针、引用、迭代器,不会造成失效
(3).list没有提供容量,空间重新分配等操作函数,每个元素都有自己的内存
(4).list也提供了特殊成员函数,专门用于移动元素。和同名算法相比,速度更快

由于在vector的头部插入新元素的效率非常低,所以只在list中有push_front()

cout.width(5);//格式化输出,宽度为5个字符
cout.precision(1);//保留1位小数点
cout<<std::fixed<<str;//以定点数形式输出
cout<<cout.scientific<<str;//以科学计数法输出 

通过函数完成两个list容器中元素交换的同时,容器的大小也发生了变化。

3.4.4其他重要成员函数
merge();合并两个list型对象为一个list对象。
合并之后的容器中元素是按从小到大升序排序的,源list的东西一直存在
list.sort(greater<int>());在sort中是降序排序排列
splice();插入合并,源list里的东西会被移除
unique();移除相邻重复元素,仅留下一个

3.5序列式容器--deque(双端队列)类模板 
resize()是重新分配大小,有值就不会覆盖,原来的太大就会裁剪,太小就会补
提供了[],可用下标来访问


3.6关联式容器概述
<set>头文件有set、multiset
<map>头文件有map、multimap
都是自动排序的。
set中元素必须是唯一的
multiset中元素可以不唯一,一般可以使程序按照次序存储一组数值
map中键值是唯一的
multimap是一种允许出现重复关键值的关联数组容器。与map对象不同
一个关键词可以和多个元素相联系,multimap允许键值重复

对类对象pair<A,B> gg;一般用来给map赋值/取值,
返回的是一个迭代器,也用来判断对set的insert成功没
A用gg.first表示,B用gg.second表示

set/multiset
元素一旦被输入容器中,就无法再对其进行必要的访问,因为元素的位置改变了
原有的输入顺序被自动排序功能打乱。要改变元素的值,需要先删除原有的元素地,
再重新插入新元素(自动排序)

两种形式实现排序规则
std::set<int,std::greater<int> >s1;  //模板参数形式  !!!注意:有个空格!!!
set<int>s2(less<int>());      //构造参数形式

low_bound(const Key& key);返回一个指向集合中键值大于等于参数Key的第一个元素
upper_bound(const Key& key);返回一个指向集合中键值大于参数Key的第一个元素

equal_range(const Key&key);返回的是一个迭代器对(pair)
pair<set<int>::iterator,set<int>::iterator>p1;
p1.first指向集合中键值大于并等于参数key的第一个元素
p1.second指向集合中键值大于参数Key的第一个元素 
这就是查找一个范围内的同值子集,找不到就指向list的end



3.7.3set和multiset的迭代器相关函数和赋值函数
无法对set/multiset元素调用任何变动性算法,并且对于set/multiset不能使用
remove()算法,要移除其中的元素,要用成员函数erase(),clear()

distance()返回两个元素的距离,一般要加1,因为下标是从0开始的

3.7.5 set/multiset的比较运算符
key_compare key_comp() const;  //比较集合是升序还是降序用的
如key_compare kc1=set::key_comp();
kc1(2,3)==true就表明在set集合中第二个比第三个小,因为一般是升序排序的
value_compare value_comp() const;
这两个函数的主要作用是判断容器中元素的排序规则


3.8.2 map/multimap成员函数
map/multimap不支持元素直接存取,要通过迭代器实现,都是双向迭代器
但是map提供[]下标操作符,下标操作符的索引==键值key,通常不使用下标
直接存取map,因为容器中不存在指定键值(索引)的元素,会自动插入元素,
并且新插入的元素的value由默认构造函数提供,通常是0,所以不用[]最好
insert(iterator it,value v);所插入的元素将出现在it指出的位置之前


交换两个集合中的元素可以用swap
swap(m1,m2);//m1与m2互换
m1.swap(m2);//这里只改变了m1

函数upper_bound(Key key)返回值是返回指向大于key元素的迭代器
lower_bound(Key key)返回指向key前面元素的迭代器,即key是界限  
对插入/删除很有用


upper_bound(Key key);有重复,到最后一个key就是
lower_bound(Key key);有重复,到最前第一个不是key的就是

less<int>  从小到大
greater<int> 从大到小

骚操作
int col[]={1,5,7,2,8};
copy(col,col+5,ostream_iterator<int>(cout," ");
输出到流cout中并以空格间隔


3.9.1 bitset类模板   位操作用的东西,很强大
bitset();
bitset.to_ulong();变成整数
bitset.to_string();变成字串


4.2.5区间比较算法
equal();两个容器对象的比较,相等返回true
mismatch();比较两个容器对象不等的元素,用pair<a,b>返回找到的第一对,
如果没有找到不等的元素,也用pair<a,b>返回,a为第一个容器的end
b为第二个容器对应的地方,并不一定也是end。因为两个容器不一定等长

lexicographical_compare();
(1)元素不等,返回的比较结果为两个序列的结果
(2)容器不等长,又第一个容器是短容器,返回true
(3)容器等长,都相等,返回false




4.3.4赋值










猜你喜欢

转载自blog.csdn.net/duling2/article/details/84075695