1、C++容器的版本
C++标准库具有多个版本,以下三个STL版本最为常用:
1. HP STL 其他版本的C++ STL,一般是以HP STL为蓝本实现出来的,HP STL是C++ STL的第一个实现版本,而且开放源代码。
2. P.J.Plauger STL 由P.J.Plauger参照HP STL实现出来的,被Visual C++编译器所采用,不是开源的。
3. SGI STL 由Silicon Graphics Computer Systems公司参照HP STL实现,被Linux的C++编译器GCC所采用,SGI STL是开源软件,源码可读性甚高。
本文数据结构以SGI STL为准。
2、容器的底层
在SGI STL(Standard Template Library)中,容器是由模板类定义的。这些容器包括 vector、list、deque、set、map 等等。那么,什么是模板呢?
模板类是一种通用的类定义,在实例化时可以根据具体的类型来生成具体的类实现。
通过使用模板,STL 实现了通用化的容器,可以存储不同类型的数据。而具体的容器实现则根据模板参数的不同,生成特定类型的容器。这样,可以编写一份通用的代码定义,用于处理各种类型的容器,而不需要为每种容器类型单独编写代码。
类模板由模板说明和类说明构成:
template <类型形式参数表>
类声明
template <typename Type>
class ClassName{
public:
//ClassName的成员函数
private:
Type DataMember;
}
以下为一个具体的例子
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
class MyTemplate{
public:
explicit MyTemplate(T x = 0);
T getvalue();
void showvalue();
void getType();
private:
T value;
};
template <typename T>
MyTemplate<T> :: MyTemplate(T x) : value(x){}
template <typename T>
T MyTemplate<T>::getvalue(){
return this->value;
}
template <typename T>
void MyTemplate<T> :: getType(){
cout << "variable's type is :" << typeid(this->value).name() << endl;
}
template <typename T>
void MyTemplate<T> :: showvalue(){
cout << this->getvalue() << endl;
}
int main(){
MyTemplate<int> a(10);
MyTemplate<char> b('b');
a.showvalue();
a.getType();
b.showvalue();
b.getType();
return 0;
}
以上代码的运行结果为
10
variable's type is :i
b
variable's type is :c
以上代码可以分为三个部分:模板类MyTemplate的定义、模板类MyTemplate类外成员函数的定义、mian函数。
2.1、先看模板类MyTemplate的定义
template <typename T>
class MyTemplate{
public:
explicit MyTemplate(T x = 0);
T getvalue();
void showvalue();
void getType();
private:
T value;
};
在模板类的定义中,template 的T表示占符位,本身没有实际意义,用T或者Type都可以。这里的T表代表了一个不确定的数据类型,可以为任意的数据类型,可以是int、double、char等,而具体是那个类型则是创建对象的时候指定。
这样就可以达到模板类处理任何数据类型的目的,提高代码的复用率。
2.2、模板类MyTemplate类外成员函数的定义
template <typename T>
MyTemplate<T> :: MyTemplate(T x) : value(x){}
template <typename T>
T MyTemplate<T>::getvalue(){
return this->value;
}
template <typename T>
void MyTemplate<T> :: getType(){
cout << "variable's type is :" << typeid(this->value).name() << endl;
}
template <typename T>
void MyTemplate<T> :: showvalue(){
cout << this->getvalue() << endl;
}
在每一个成员函数的定义都包含“template ”和“MyTemplate”,表明这是一个模板类MyTemplate的成员函数。
在getType()函数中,使用 typeid 运算符来输出变量的数据类型,可以更加直观的提现数据类型不定这一特点。
2.3、mian函数
int main(){
MyTemplate<int> a(10);
MyTemplate<char> b('b');
a.showvalue();
a.getType();
b.showvalue();
b.getType();
return 0;
}
main函数中,创建了两个模板类MyTemplate的对象a和b,并在创建时指定了数据的类型,随后调用了模板类MyTemplate的成员函数。
3.容器底层的具体实现
以下节选自vector容器的部分代码:
template <class _Ty, class _Alloc = allocator<_Ty>>
class vector{
public:
iterator begin() {return _Myfirst;}
iterator end() {return _Mylast;}
size_type size() const {return size_type(end() - begin());}
size_type capacity() const {return size_type(_Myend - begin());}
bool empty() const {return begin() == end();}
reference operator[] (size_type n) {return *(begin() + n);}
reference front() { return *begin();}
reference back() {return *(end()-1);}
...
};
可以看出,容器的底层确实是用template模板来建立的,但是对于底层实现机制不仔细讨论,感兴趣的可以去看源代码,以下几篇博客可以参考:
https://blog.csdn.net/aruewds/article/details/117375364
https://c.biancheng.net/view/6901.html