概述
介绍几个allocator的源码实现:简单的对operator new和operator delete进行封装的实现,vs2015中的实现,STLport中的实现,仿造STLport实现内存池。
1. 参考
http://www.cplusplus.com/reference/memory/allocator/
《STL源码剖析》
《C++ Primer 第五版》
《Generic Programming and the STL》(《泛型编程和STL》)
MSDN
2. 介绍
std::allocator是STL容器使用的内存配置器,也是标准库唯一预定义的内存配置器。
3. 实现一:最简单的实现
3.1 程序实现
template<class T>
class allocator
{
public:
// 1、为什么需要下面这些成员,有什么作用呢?
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; // size_t是无符号整数
// ptrdiff_t是有符号整数,代表指针相减结果的类型
typedef ptrdiff_t difference_type;
// 2、这是做什么用的,为何template是U,而不是与allocator的T一致?
template<class U>
struct rebind
{
typedef allocator<U> other;
};
// 默认构造函数,什么都不做
allocator() noexcept
{
}
// 泛化的构造函数,也什么都不做
// 3、为什么需要这个泛化的构造函数,不同类型的allocator复制合适吗?
template<class U>
allocator(const allocator<U>&) noexcept
{
}
// 析构函数,什么都不做
~allocator() noexcept
{
}
// 返回对象地址
pointer address(reference val) const noexcept
{
//non-const版调用const版,参见《Effective C++》条款3
return const_cast<reference>(address(static_cast<const_reference>(val)));
}
// 返回对象地址
const_pointer address(const_reference val) const noexcept
{
return &val;
}
// 申请内存,count是指对象个数,不是字节数。
// 4、hint是做什么的?
pointer allocate(size_type count, allocator<void>::const_pointer hint = nullptr)
{
return static_cast<pointer>(::operator new(count * sizeof(value_type)));
}
// 释放内存
void deallocate(pointer ptr, size_type count)
{
::operator delete(ptr);
}
// 可配置的最大量(指对象个数,不是字节数)
size_type max_size() const noexcept
{
return (static_cast<size_type>(-1) / sizeof(value_type));
}
// 构造对象,Args是模板参数包,见《C++ Primer》第5版16.4节
template <class U, class... Args>
void construct(U* p, Args&&... args)
{
::new ((void *)p) U(::std::forward<Args>(args)...);
}
// 析构对象
template <class U>
void destroy(U* p)
{
p->~U(); // 原来模板还可以这样用
}
};
// 5、为什么要对void进行特化?
template<>
class allocator<void>
{
public:
typedef void value_type;
typedef void *pointer;
typedef const void *const_pointer;
template <class U> struct rebind
{
typedef allocator<U> other;
};
};
3.2 问题解答
1、STL的规范,同时这些type在迭代器和traits技术中有用。
2、摘自MSDN:A structure that enables an allocator for objects of one type to allocate storage for objects of another type.
This structure is useful for allocating memory for type that differs from the element type of the container being implemented.
The member template class defines the type other. Its sole purpose is to provide the type name allocator<_Other>, given the type name allocator<Type>.
For example, given an allocator object al of type A, you can allocate an object of type _Other with the expression:
A::rebind<Other>::other(al).allocate(1, (Other *)0)
Or,