欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

读书笔记:STL源码剖析之STL概论

程序员文章站 2022-07-12 18:07:56
...

STL六大部件:容器,算法,迭代器,仿函数,配接器,配置器

六大组件的交互关系: Container通过 Allocator取得数据储存空间, Algorithm通过 Iterator存取 Container内容, Functor可以协助 Algorithm完成不同的策略变化, Adapter可以修饰或套接 Functor.

STL发展:PH-》PJ-》RW-》SGI

常用STL头文件:vector.h deque.h list.h map.h algo.h function.h……

SGI头文件(STL真正实现于此):stl_vector.h stl_deque.h stl_list.h stl_map stl_function.h
STL标准头文件(无扩展名):algorithm deque functional hash_map hash_set iterator list map memory set stack

编译器组态设置:<stl_config.h>定义许多常量,标志某些组态的成立与否,以条件式写法,让预处理器根据各个常量决定取舍哪个程序段代码。

临时对象的产生与运用:
调用相应的constructor且不指定对象名称:int(8);常用于仿函数与算法的搭配

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

template<typename T>
class print
{
public:
	//()重载
	void operator()(const T& elem)
	{
		cout<<elem<<" ";
	}
};

int main()
{
	int ia[6]={0,1,2,3,4,5};
	vector<int> iv(ia,ia+6);
	//print<int>()是一个临时对象,不是一个函数调用操作
	for_each(iv.begin(),iv.end(),print<int>());//()是已经重载过了。结果打印出:0 1 2 3 4 5
   /*
	for_each()事实上是個 function template,其实质如下  [effective STL item 41]
	template<typename InputIterator, typename Function>
	Function for_each(InputIterator beg, InputIterator end, Function f) {
		while(beg != end) 
			f(*beg++);
	}
   */
	getchar();
	return 0;
}

静态常量整数成员在class内部直接初始化

#include <iostream>
using namespace std;
template <typename T>
class testclass
{
 public:// expedient
	 static const int _datai =5;
	 static const long _datal =3L;
	 static const char _datac ='c';
	
};

int main()
{
	cout<<testclass<int>::_datai<< endl; //5
	cout<<testclass<int>::_datal<< endl; //3
	cout<<testclass<int>::_datac<< endl; //c
    getchar();
	return 0;
}

increment/decrement/dereference操作符
increment/dereference操作符在代器的实现上占有非常重要的地位,因为任何一个迭代器都必须实现出前进(increment, operator++)和取值(dereference operator*)功能,前者还分为前置式(prefix和后置式(postfix)两种,有非常规律的写法14.有些迭代器具备双向移动功能,那么就必须再提供 decrement操作
符(也分前置式和后置式两种)

#include <iostream>
 using namespace std;
 class INT
 {
	 friend ostream& operator<<(ostream& os, const INT& i);
 public:
		 INT (int i): m_i(i) {};
	// prefix: increment and then fetch
	 INT& operator++()
	{
		++(this->m_i);//随着 class的不同,该行应该有不同的操作
		 return *this;
	}
	 // postfix fetch and then increment
		 const INT operator++(int)
		 {
			 INT temp = *this;
	         ++(*this);
		      return temp;
		 }
	 // prefix decrement and then fetch
		 INT& operator--()
	   {
		 --(this->m_i);//随着 class的不同,该行应该有不同的操作
		 return *this;
	   }
	// postfix fetch and then decrement
		 const INT operator--(int)
		 {
			 INT temp = *this;
	          --(*this);
		      return temp;
		 }
		 // dereference
		 int& operator*() const
		 {
			 return (int&)m_i;
		 //以上转换操作告诉编译器,你确实要将 const int转为non- const Ivalue
		//如果没有这样明白地转型,有些编译器会给你警告,有些更严格的编译器会视为错误
		 }
 private:
	 int m_i;
 };

 ostream& operator<< (ostream& os, const INT& i)
 {
	 os<<'['<<i.m_i<<']';
	 return os;
 }
 int main()
 {
	 /*
	 [5]
	 [7]
	 [7]
	 [5]
	 5
	 */
	 INT I(5);
	 cout<<I++<<endl;
	 cout<<++I<<endl;
	 cout<<I--<<endl;
	 cout<<--I<<endl;
	 cout<<*I<<endl;
	 system("pause");
	 return 0;
 }

仿函数:
如果我们在一个类中重载了()运算符。那么这个类的对象就可以像调用函数一样去调用 。
仿函数在STL中的定义 #include

下面是一个将 operator()重载的例子:

#include <iostream>
using namespace std;
//由于将 operator()重载了,因此plus成了一个仿函数
template <class T>
struct plus
{
	T operator() (const T& x, const T& y) const {return x+y;}
};
//由于 operator将()重载了,因此 minus成了一个仿函数
template <class T>
struct minus
{
	T operator()(const T& x, const T& y) const {return x-y;}
};
int main()
{
	    //以下产生仿函数对象
		plus<int> plusobj;
		minus<int> minusobj;
		//以下使用仿函数,就像使用一般函数一样
		cout<< plusobj(3,5)<<endl;//8
		cout<< minusobj(3,5)<<endl;//-2
		//以下直接产生仿函数的临时对象(第一对小括号),并调用之(第二对小括号)
		cout << plus<int>()(43, 50) << endl; //93
		cout << minus<int>()(43, 50)<< endl; //-7
		system("pause");
		return 0;
}

来源:《STL源码分析》

相关标签: c++ stl

上一篇: Ajax

下一篇: Ajax