练习16.58:
StrVec:
#include <iostream>
#include <string>
using namespace std;
#include <vector>
#include <algorithm>
#include <set>
//类vector类内存分配策略的简化实现
class StrVec {
public:
//默认初始化
StrVec();
//拷贝构造函数
StrVec(const StrVec&);
//拷贝赋值运算符
StrVec& operator=(const StrVec&);
//析构函数
~StrVec();
//拷贝元素
void push_back(const std::string&);
//数组大小和容量
size_t size()const;
size_t capacity()const;
//获得数组的首元素和尾后元素
std::string* begin()const;
std::string* end()const;
//emplace_back()
template<class... Args>void emplace_back(Args&&...);
void reserve(size_t n);
void resize(size_t n);
private:
//静态成员,用来分配元素
static std::allocator<std::string>alloc;
//工具函数,被添加元素的函数所使用
void chk_n_alloc();
//工具函数,被拷贝构造函数、赋值运算符和析构函数使用
std::pair<std::string*, std::string*>alloc_n_copy(const std::string*, const std::string*);
//销毁元素并释放内存
void free();
//获得更多内存并拷贝已有元素
void reallocate();
//指向数组首元素的指针
std::string* elements;
//指向数组第一个空闲元素的指针
std::string* first_free;
//指向数组尾后位置的指针
std::string* cap;
};
std::allocator<string> StrVec::alloc;
//emplace_back()
template<class... Args>
inline void StrVec::emplace_back(Args&&...)
{
chk_n_alloc();
alloc.construct(first_free++, std:: forward<Args>(args)...);
}
int main()
{
system("pause");
return 0;
}
Vec:
template<typename T>class Vec {
public:
//默认初始化
Vec() :elements(nullptr), first_free(nullptr), cap(nullptr) { };
//拷贝构造函数
Vec(const Vec&);
//拷贝赋值运算符
Vec& operator=(const Vec&);
Vec(initializer_list<T>);
//析构函数
~Vec();
//拷贝元素
void push_back(const T&);
//数组大小和容量
size_t size()const;
size_t capacity()const;
//获得数组的首元素和尾后元素
T* begin()const;
T* end()const;
//emplace_back()
template<class... Args>void emplace_back(Args&&...);
void reserve(size_t n);
void resize(size_t n);
private:
//静态成员,用来分配元素
static std::allocator<T>alloc;
//工具函数,被添加元素的函数所使用
void chk_n_alloc()
{
if (size() == capacity()) reallocate();
}
//工具函数,被拷贝构造函数、赋值运算符和析构函数使用
std::pair<T*, T*>alloc_n_copy(const T*, const T*);
//销毁元素并释放内存
void free();
//获得更多内存并拷贝已有元素
void reallocate();
//指向数组首元素的指针
T* elements;
//指向数组第一个空闲元素的指针
T* first_free;
//指向数组尾后位置的指针
T* cap;
};
template<typename T>
std::allocator<T> Vec<T>::alloc;
//emplace_back()
template<typename T>
template<class... Args>
inline void Vec<T>::emplace_back(Args&&...)
{
chk_n_alloc();
alloc.construct(first_free++, std:: forward<Args>(args)...);
}
练习16.59:
s是一个左值,通过forward将其传入construct函数,还是一个左值。然后进行拷贝构造
练习16.60:
make_shared也是通过forward进行工作的,方式与emplace_back()类似。传入参数包,扩展,然后构造指向vector<T>的智能指针
练习16.61:
make_shared实现如下所示:
template<typename T, class ...Args>
SharedPtr<T>MakeShared(Args&&...args)
{
return SharedPtr<T>(new T(std::forward<Args>(args)...));
}