文章目录
前言
配置器的功能在于定义类中内存的分配,一般情况下程序员是不会自定义内存的分类的。
一.STL allocator配置器详解
allocator是STL中非常重要的配置器,用于配置空间内存,在各种Containers中都存在,只是我们在使用时,allocator对我们来说完全是透明的。
1.在容器中感受allocator
//deque get_allocator
void test1(){
deque<int> mydeque;
int *p = mydeque.get_allocator().allocate(5);
for (int i = 0; i < 5; i++){
mydeque.get_allocator().construct(&p[i], i);
cout << p[i] << endl;
}
mydeque.get_allocator().destroy(p);
mydeque.get_allocator().deallocate(p, 5);
p = NULL;
}
//map get_allocator
void test2(){
map<char, int> mymap;
pair<const char,int> *p = mymap.get_allocator().allocate(4);
for (int i = 0; i < 4; i++){
mymap.get_allocator().construct(&p[i], make_pair('a' , 1));
cout << p->first << ", " << p->second << endl;
}
mymap.get_allocator().destroy(p);
mymap.get_allocator().deallocate(p, 4);
}
2.std::allocator的基本用法
void test3(){
std::allocator<int> a1;
int *p1 = a1.allocate(3);
a1.construct(&p1[0], 100);
a1.construct(&p1[1], 200);
a1.construct(&p1[2], 300);
cout << p1[0] << endl;
cout << p1[1] << endl;
cout << p1[2] << endl;
a1.destroy(p1);//析构p1指向的对象
cout << "----------after destory-----------" << endl;
cout << p1[0] << endl;
cout << p1[1] << endl;
cout << p1[2] << endl;
a1.deallocate(p1, 1);
}
3.std::allocator的泛型编程
template<typename T>
void test4(const T& val){
allocator<T> a1;
T *p = a1.allocate(1);
a1.construct(p, val);
cout << *p << endl;
a1.destroy(p);
a1.deallocate(p, 1);
}
4.allocator配置类类型
注意:
reserve 与 resize:
1.在进行reserve申请空间的时候,对象并没有初始化,只是单纯的申请空间
2.而在进行resize的时候,则是会调用构造函数初始化类
copy 与 uninitialized_copy
1.copy调用=运算符
2.uninitialized_copy 调用const X& 拷贝运算符
class X
{
public:
X() : _data(0) { cout << "X()" << endl; }
X(int x) : _data(x) { cout << "X(int)" << endl; }
X(const X &rhs)
: _data(rhs._data)
{
cout << "X(const X & )" << endl;
}
X& operator=(const X& lhs){
cout << "operator=()" << endl;
_data = lhs._data;
return *this;
}
operator int()
{
return _data;
}
~X() { _data = 0; cout << "~X()" << endl; }
private:
int _data;
};
/*
*/
void test0()
{
vector<X> vec1;
vec1.reserve(10);
vec1.resize(3);
vec1[0] = 1;
vec1[1] = 2;
vec1[2] = 3;
cout << "----------" << endl;
allocator<X> a;
X *p = a.allocate(3);
// std::copy(vec1.begin(), vec1.end(), p);
// std::uninitialized_copy(vec1.begin(), vec1.end(), p);
cout << p[1] << endl;
}
void test1()
{
allocator<X> alloc;
X *arr = alloc.allocate(3);
arr[0] = X(1);
arr[1] = X(2);
arr[2] = X(3);
cout << arr[0] << endl;
cout << arr[1] << endl;
cout << arr[2] << endl;
alloc.destroy(arr);//析构arr指向的对象
alloc.destroy(arr+1);
alloc.destroy(arr+2);
cout << "-------------------------after destroy" << endl;
cout << arr[0] << endl;
cout << arr[1] << endl;
cout << arr[2] << endl;
alloc.deallocate(arr, 3);
}
二.通过allocator实现Vector类
仿照sgi_stl 中的 stl_vector.h简单实现自己的Vector类
#include <iostream>
#include <memory>
#include <string.h>
using std::allocator;
using std::cout;
using std::endl;
/*
仿照sgi_stl 中的 stl_vector.h
简单实现自己的Vector类
*/
template <typename T>
class MyVector
{
public:
MyVector(size_t n = 0);
~MyVector();
const T *begin() const { return _begin; }
const T *end() const { return _end; }
ptrdiff_t size() const { return _end - _begin; }
ptrdiff_t capacity() const { return _endCapacity - _begin; }
T &operator[](int idx) const { return _begin[idx]; }
void push_back(const T &);
void pop_back();
private:
void reallocVector();
private:
T *_begin;
T *_end;
T *_endCapacity;
static allocator<T> _alloc;
};
template <typename T>
allocator<T> MyVector<T>::_alloc;
/**********************************************************/
template <typename T>
MyVector<T>::MyVector(size_t n)
{
cout << "MyVector()" << endl;
_begin = _alloc.allocate(n);
_end = _begin + n;
_endCapacity = _begin + n;
}
template <typename T>
MyVector<T>::~MyVector()
{
cout << "~MyVector()" << endl;
_alloc.destroy(_begin);
_alloc.deallocate(_begin, capacity());
_begin = NULL;
_end = NULL;
_endCapacity = NULL;
}
template <typename T>
void MyVector<T>::push_back(const T &ele)
{
if (size() == capacity())
{
reallocVector();
}
_alloc.construct(_end++, ele);
}
template <typename T>
void MyVector<T>::pop_back()
{
if (size() == 0)
{
return;
}
_alloc.destroy(--_end);
}
template <typename T>
void MyVector<T>::reallocVector()
{
cout << "reallocVector" << endl;
size_t newCapacity = (size()==0)? 1:size() * 2;
T *temp = _alloc.allocate(newCapacity);
memcpy(temp, _begin, size() * sizeof(T));
auto it = begin();
while(it!=_end){
_alloc.destroy(it);
it++;
}
_alloc.deallocate(_begin, capacity());
_begin = temp;
_end = _begin + newCapacity / 2;
_endCapacity = _begin + newCapacity;
temp = NULL;
}
int main()
{
MyVector<int> vec;
vec.push_back(1);
vec.push_back(2);
cout << vec[0] << endl;
cout << vec[1] << endl;
cout << "size:" << vec.size() << endl;
cout << "capacity:" << vec.capacity() << endl;
return 0;
}