STL源码分析-第一章
第一章 STL概述 可能令你困惑的C++语法 1....
一般接口(generalized)
allocator::value_type
allocator::pointer
allocator::const_pointer
allocator::reference
allocator::const_reference
allocator::size_type
allocator::difference_type
特殊化接口(specified)
接口 | 接口 |
---|---|
allocator::rebind | 旨在帮助allocator为不同类型的元素分配空间,即使allocator已被指定为一个对象分配空间。 |
allocator::allocator() | 默认构造函数 |
allocator::allocator(const allocator&) | 拷贝函数 |
template<class U>allocator::allocator(const allocator<U>&) | 泛型拷贝函数 |
allocator::~allocator() | 默认析构函数 |
pointer allocator::address(reference x) const | 返回指定对象的地址,例如:a.address(x) <=> &x |
pointer allocator::allocate(size_type n, const void* = 0) | 配置空间,用来存储n个类型为T的对象,第二个参数主要用于优化内存优化和管理 |
allocator::deallocate(pointer p, size_type n) | 释放之前所分配的内存 |
allocator::allocator::max_size() const | 返回所成功分配的最大内存大小的值 |
allocator::destroy(pointer p) | 等价于 p->T() |
用一个例子对allocator::rebind
进行补充:
template<class T>
class alloc;
template<typename T, typename Alloc = alloc<T>>
class MyContainer{
public:
template<typename U>
struct rebind{
typedef Alloc<U> other; // Allocator type for type U
// other represents some other objects
};
};
#ifndef T_ALLOC_
#define T_ALLOC_
#include <new> // for placement new
#include <cstddef> // for ptrdiff_t, size_t
#include <cstdlib> // for exit()
#include <climits> // for UINT_MAX
#include <iostream> // for cerr
#include <vector> // for test
namespace T_ {
// allocate memory
template<class T>
inline T* _allocate(ptrdiff_t size, T*) {
std::set_new_handler(0); // invoke when out of memory
T* tmp = (T*)(::operator new((size_t)(size * sizeof(T)))); // allocate memory
if (tmp == 0) { // the allocated memory is 0, which means that allocating memory fails
std::cerr << "out of memory" << '\n';
exit(0); // terminate processs
}
return tmp; // return the pointer of the allocated memory block
}
// release memory
template<class T>
inline void _deallocate(T* buffer) {
::operator delete(buffer); // release the allocated memory
}
// constructor
template<class T1, class T2>
inline void _construct(T1* p, const T2& value) {
new(p) T1(value); // assign value at pointer p
}
// destructor
template<class T>
inline void _destroy(T* ptr) {
ptr->~T(); // invoke the destructor of type class
}
template<class T>
class allocator {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
/*-----implement part of the specific API-----*/
// allocator::rebind->rebind allocator of type U
template<class U>
struct rebind {
typedef allocator<U> other;
};
// pointer allocator::allocate->hint used for locality
pointer allocate(size_type n, const void* hint = 0) {
return _allocate((difference_type)n, (pointer)0);
}
// allocator::deallocate
void deallocate(pointer p, size_type n) { _deallocate(p); }
// allocator::construct
void construct(pointer p, const T& value) {
_construct(p, value);
}
// allocator::destroy
void destroy(pointer p) { _destroy(p); }
// pointer allocator::address
pointer address(reference x) { return (pointer)&x; }
// const_pointer allocator::const_address
const_pointer const_address(const_reference x) {
return (const_pointer)&x;
}
// size_type allocator::max_size()
size_type max_size() const {
return size_type(UINT_MAX / sizeof(T));
}
};
}
#endif
int main() {
int ia[5] = { 0, 1, 2, 3, 4 };
unsigned int i;
std::vector<int, T_::allocator<int>> iv(ia, ia + 5);
for (i = 0; i < iv.size(); i++) std::cout << iv[i] << ' ';
std::cout << '\n';
return 0;
}