TinySTL 之 allocator 接口介绍
提示:此篇文章需要了解 C++ 泛型编程的一些概念才能看得懂本文章。
在学习 STL 设计的时候,最先学习的肯定是 allocator,这对应的是内存空间的分配和对象的建立。下面是 allocator 用到的接口
成员类型
alloctor 数据成员
类型 | 定义 |
---|---|
value_type | T |
pointer | T* |
const_pointer | const T* |
reference | const T& |
const_reference | const T& |
size_type | std::size |
difference_type | std::ptrdiff_t |
成员函数
alloctor 成员函数
函数 | 定义 |
---|---|
static T* allocate(); | 分配未初始化的存储 |
static T* allocate(size_type n); | 分配未初始化的存储 |
static void deallocate(T *ptr); | 释放分配的内存 |
static void deallocate(T *ptr, size_type n); | 释放分配的内存 |
static void construct(T *ptr); | 释放分配的内存 |
static void construct(T *ptr, const T &value); | 在分配的内存创建对象 |
template <class... Args> static void construct(T *ptr, T &&value); | 在分配的内存创建对象 |
static void destroy(T *ptr); | 析构在内存中分配的对象 |
static void destroy(T *first, T *last); | 析构在内存中分配的对象 |
这个接口的设计来自于 std::allocate 的接口介绍。
源码
关于源码部分的实现,主要借鉴于 STL 源码剖析这本书,并且 C++11 的一些新特性实现,通过模板
#ifndef TINYSTL_ALLOCATOR_H_
#define TINYSTL_ALLOCATOR_H_
// 这个头文件包含一个模板类 allocator,用于管理内存的分配、释放,对象的构造、析构
#include "stl_construct.h"
#include "util.h"
namespace TinySTL
{
// 模板类:allocator
// 模板函数代表数据类型
template <typename 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;
public:
static T* allocate();
static T* allocate(size_type n);
static void deallocate(T* ptr);
static void deallocate(T* ptr, size_type n);
static void construct(T* ptr);
static void construct(T* ptr, const T& value);
static void construct(T* ptr, T&& value);
template <typename... Args>
static void construct(T* ptr, Args&& ...args);
static void destroy(T* ptr);
static void destroy(T* first, T* last);
};
template <typename T>
T* allocator<typename T>::allocate()
{
return static_cast<T*>(::operator new(sizeof(T)));
}
template <typename T>
T* allocator<T>::allocate(size_type n)
{
if (n == 0)
return nullptr;
return static_cast<T*>(::operator new(n * sizeof(T)));
}
template <typename T>
void allocator<T>::deallocate(T* ptr)
{
if (ptr == nullptr)
return;
::operator delete(ptr);
}
template <typename T>
void allocator<T>::deallocate(T* ptr, size_type /*size*/)
{
if (ptr == nullptr)
return;
::operator delete(ptr);
}
template <typename T>
void allocator<T>::construct(T* ptr)
{
TinySTL::construct(ptr);
}
template <typename T>
void allocator<T>::construct(T* ptr, const T& value)
{
TinySTL::construct(ptr, value);
}
template <typename T>
void allocator<T>::construct(T* ptr, T&& value)
{
TinySTL::construct(ptr, TinySTL::move(value));
}
template <typename T>
template <typename...Args>
void allocator<T>::construct(T* ptr, Args&& ...args)
{
TinySTL::construct(ptr, TinySTL::forward(args)...);
}
template <typename T>
void allocator<T>::destroy(T* ptr)
{
TinySTL::destroy(ptr);
}
template <typename T>
void allocator<T>::destroy(T* first, T* last)
{
TinySTL::destroy(first, last);
}
} // namespace TinySTL
#endif // !TINYSTL_ALLOCATOR_H_
测试
测试的例子如下