【C++STL】C++ Standard Template Library三个重要元素

一、STL三个最重要的元素是容器,迭代器,算法
1.容器
容器是用来管理其他对象的对象,让用户来决定是使用值还是引用。容器一般用模板类来实现。STL并没有采用面向对象的技术,所以STL中并没有一个通用的容器类,即没有统一的基类。


2.迭代器

迭代器的工作方式如指针。根据不同的应用,它可能是普通的指针或者是对象指针。迭代器通常用来获取

容器中的元素,可以从第一个元素移动到另外一个元素,这些操作对外面都是隐藏的。
所有的迭代器都有++,解引用*,比较(==或!=)的能力。如果该迭代器不是一个普通的指针而是一个迭代对象,可以通过下面的函数来实现上面的功能。
// scheme of a simple iterator:
template<class T>
class Iterator {
public:
// constructors, destructor ....
bool operator==(const Iterator<T>&) const;
bool operator!=(const Iterator<T>&) const;
Iterator<T>& operator++(); // prefix
Iterator<T> operator++(int); // postfix
T& operator*() const;
T* operator->() const;
private:
// association with the container ...
};

3.算法
模板算法通过迭代器访问容器,不仅对用户自定义的数据类型支持,而且对C++内部的数据类型也支持。
 它们三者之间的关系就是:容器让迭代器可用,而算法则靠它们俩来实现。
  容器-->迭代器-->算法
            <--      <--

下面的程序用来说明用C数组和STL来实现函数find()的不同:

Example 1:不使用STL

#include<iostream> 
using namespace std;
typedef const int* IteratorType;//迭代器类型


IteratorType find(IteratorType begin, IteratorType end,
const int& Value) {
while(begin != end // 指针比较
&& *begin != Value) // 解引用并且对象比较
++begin; // 移动到下一个位置
return begin;
}

int main() {
const int Count = 100;
int aContainer[Count]; // 定义容器
IteratorType begin = aContainer; // 指向初始元素的指针
// 最后一个元素的后一个位置
IteratorType end = aContainer + Count;
// 用偶数填充容器
for(int i = 0; i < Count; ++i)
aContainer[i] = 2*i;


int Number = 0;
while(Number != -1)
{
cout << " 输入一个数字 (-1 = end):";
cin >> Number;
if(Number != -1) 
{ 
IteratorType position = find(begin, end, Number);
if (position != end)
cout << "元素的位置为: "<< (position - begin) << endl;
else
cout << Number << " 没有找到!" << endl;

}
}

}

从上面的程序可以看出,find()算法不需要知道容器的信息,仅仅通过指针(迭代器)来实现下面的功能:
a.++操作,实现移动到下一个元素
b.*操作解引用  c.这个指针必须允许通过!=进行比较运算

Example 2:通过模板来实现find函数。

template<class Iteratortype, class T>
Iteratortype find(Iteratortype begin, Iteratortype end,
const T& Value) 
{
while(begin != end&& *begin != Value) // 迭代器比较
++begin; 
return begin; 

}

这个函数允许迭代器的类型Iteratortype可以使用任何名字。

Example 3:使用STL,利用vector<T>类的方法来代替前面的begin和end返回迭代器

typedef vector<int>::const_iterator IteratorType;


template<class Iteratortype, class T>
Iteratortype find(Iteratortype begin, Iteratortype end,
const T& Value) {
while(begin != end // iterator comparison
&& *begin != Value) // object comparison
++begin; // next position
return begin;
}
int main() 
{

const int Count = 100;
vector<int> aContainer(Count); // define container
for(int i = 0; i < Count; ++i) // fill container with
aContainer[i] = 2*i; // even numbers
int Number = 0;
while(Number != -1) 
{
cout << " enter required number (-1 = end):";
cin >> Number;
if(Number != -1)
{
// use global find() defined above
IteratorType position =::find(aContainer.begin(), // use of container methods:
aContainer.end(), Number);
if (position != aContainer.end())
cout << "found at position "<< (position - aContainer.begin()) << endl;
else cout << Number << " not found!" << endl;

}

二、STL内部运作原理

下面通过用户自定义的类slist来说明STL的内部机制。为了保证这个类的迭代器不仅仅是一个简单的指针,该例子中不使用vector,使用单链表的形式。故不能通过索引随机访问该类中的元素。因此,这个容器通过方法push_front()来填充元素。函数find()用来表明用户自定义的类的行为和STL类的行为一样。slist的数据以及指向下一个元素的指针存放在private部分,并且提供一个公开的迭代器,这个迭代器对象保存了当前容器当前位置的属性值。
slist.h头文件

#ifndef SIMPLELIST_H
#define SIMPLELIST_H
namespace br_stl
{
#include<cassert>
#include<iterator>
template<class T>
class slist
{
 public:
typedef T value_type; 
typedef ptrdiff_t difference_type; //64位的int
typedef T* pointer;
typedef T& reference;
slist() : firstElement(0), Count(0) {}
~slist(){}
slist(const slist& sl)
: firstElement(0), Count(0)
{
if(!sl.empty()) 
{
iterator I = sl.begin();
push_front(*I++);
ListElement *last = firstElement;
while(I != sl.end()) 
{
// insert elements at the end to preserve the ordering

last->Next = new ListElement(*I++, 0);
last = last->Next;
++Count;
}

}
}


slist& operator=(const slist& sl) {
slist temp(sl);

std::swap(temp.firstElement, firstElement);
std::swap(temp.Count, Count);
return *this;
}

bool empty() const { return Count == 0;}
size_t size() const { return Count;}

void push_front(const T& Datum) 
{ // insert at beginning
firstElement = new ListElement(Datum, firstElement);
++Count;
}
private:
struct ListElement {
T Data;
ListElement *Next;
ListElement(const T& Datum, ListElement* p): Data(Datum), Next(p) {}
};

ListElement *firstElement;
size_t Count;
public:

class iterator {
public:
typedef std::forward_iterator_tag iterator_category;
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
iterator(ListElement* Init = 0)
: current(Init){}
T& operator*() { // dereferencing
return current->Data;
}
const T& operator*() const { // dereferencing
return current->Data;
}
iterator& operator++() { // prefix
if(current) // not yet arrived at the end?
current = current->Next;
return *this;
}
iterator operator++(int) { // postfix
iterator temp = *this;
++*this;
return temp;
}
bool operator==(const iterator& x) const {
return current == x.current;
}
bool operator!=(const iterator& x) const {
return current != x.current;
}

private:
ListElement* current; // pointer to current element
}; // iterator

iterator begin() const { return iterator(firstElement);}
iterator end() const { return iterator();}

iterator erase(iterator position)
{
if(!firstElement) return end(); // empty list
iterator Successor = position;
++Successor;
// look for predecessor
ListElement *toBeDeleted = position.current,
*Predecessor = firstElement;
if(toBeDeleted != firstElement) {
while(Predecessor->Next != toBeDeleted)
Predecessor = Predecessor->Next;
Predecessor->Next = toBeDeleted->Next;
}
else // delete at firstElement
firstElement = toBeDeleted->Next;
delete toBeDeleted;
--Count;
return Successor;
}

void clear() 
{
while(begin() != end())
erase(begin());
}

};

 

template<class Iterator>
int operator-(Iterator second, Iterator first)
{
int count = 0;

while(first != second
&& first != Iterator()) 
{
++first;
++count;
}
// In case of inequality, second is not reachable by first
assert(first == second);
return count;
}

 


} // namespace br_stl

#endif


主函数:

#include<algorithm> // contains find()
#include<iostream>
#include"slist.h" 
int main() 
{

const int count = 100;
br_stl::slist<int> aContainer; // 定义容器
for(int i = count; i >= 0; --i) 
{ // fill the container with
aContainer.push_front(2*i); // even numbers
}

int Number = 0;
while(Number != -1) {
std::cout << " enter required number (-1 = end):";
std::cin >> Number;
if(Number != -1) {
// use of container methods:
br_stl::slist<int>::iterator Position =
std::find(aContainer.begin(),
aContainer.end(), Number);
if(Position != aContainer.end())
std::cout << "found at position "
<< (Position - aContainer.begin())
<< std::endl;
else
std::cout << Number << " not found!"
<< std::endl;
}
}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值