TinySTL 之建构和结构工具 stl_construct
提示:此篇文章需要了解 C++ 泛型编程的一些概念才能看得懂本文章。
STL 有 6 大部件,其中 allocator 对应的就是函数中的内存分配与对象建立,而为了减少代码量,allocator 把这部分的工作剥离开放到了 stl_construct.h 中,使用
注意,这里可能会用到后面使用到的例子,例如 ForwardIter,表示的是容器的迭代器,不过都很好理解。
无成员类型
成员函数
construct 成员函数
函数 | 定义 |
---|---|
template <typename T> void construct(T *ptr) | 构造函数1 |
template <typename T1, class T2>void void construct(T1 *ptr, const T2 &&value); | 构造函数2 |
template <typename T1, class... Args> void construct(T *ptr, Args&&... args); | 构造函数3 |
template <typename T> void destroy(T *ptr); | 析构函数1 |
template <typename ForwardIterator> void destroy(ForwardIterator first, ForwardIterator, last); | 释放分配的内存 |
template <typename T> void destroy_one(T*, std::true_type); | 释放内存 ptr |
template <typename T> void destroy_one(T*, std::false_type); | 释放内存 ptr |
template <typename ForwardIter> void destroy_cat(ForwardIter first, ForwardIter last, std::true_type); | 循环释放容器内存 |
template <typename ForwardIter> void destroy_cat(ForwardIter first, ForwardIter last, std::false_type); | 循环释放容器内存 |
源码
关于源码部分的实现,主要借鉴于 STL 源码剖析这本书,并且 C++11 的一些新特性实现,这里涉及到了不定参数模板
#ifndef TINYSTL_ALLOCATOR_H_
#define TINYSTL_ALLOCATOR_H_
// 这个头文件包含两个函数 construct,destroy
// construct : 负责对象的构造
// destroy : 负责对象的析构
#include <new>
#include "type_traits.h"
#include "iterator.h"
namespace TinySTL
{
// construct 构造对象
// 使用placement new在分配的内存ptr初始化对象,构造函数T()
template <typename T>
void construct(T* ptr)
{
::new ((void*)ptr) T();
}
// 使用placement new在分配的内存ptr初始化对象,构造函数T(value);
template <typename T1, typename T2>
void construct(T1* ptr, const T2& value)
{
::new ((void*)ptr) T1(value);
}
template <typename T, typename... Args>
void construct(T* ptr, Args&&... args)
{
::new ((void*)ptr) T(TinySTL::forward(args)...); // 使用forward实现不定参数的完美转发
}
// destroy 将对象析构
template <typename T>
void destroy_one(T*, std::true_type) {}
// 调用了析构函数 ~T(),但是 pointer 所在内存并没有释放
// 需要分配器的 operator delete(ptr) 释放
template <typename T>
void destroy_one(T* pointer, std::false_type)
{
if (pointer != nullptr)
{
pointer->~T();
}
}
template <typename ForwardIter>
void destroy_cat(ForwardIter , ForwardIter , std::true_type) {}
template <typename ForwardIter>
void destroy_cat(ForwardIter first, ForwardIter last, std::false_type)
{
for (; first != last; ++first)
destroy(&*first);
}
template <typename T>
void destroy(T* pointer)
{
destroy_one(pointer, std::is_trivially_destructible{});
}
template <typename ForwardIter>
void destroy(ForwardIter first, ForwardIter last)
{
destroy_cat(first, last, std::is_trivially_destructible<
typename iterator_traits<ForwardIter>::value_type>{});
}
} // namespace TinySTL
#endif // !TINYSTL_ALLOCATOR_H_
测试
这部分必须配合后面的 stl_allocator 一起测试,因为需要 allocator 来申请和释放内存。