#include <memory>
#include <iostream>
#include <algorithm>
namespace Ming {
template<class T> class vec
{
public:
typedef T* iterator;
typedef const T* const_iterator;
//typedef typename std::vector<T>::size_type size_type;
typedef size_t size_type;
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
//-------------------------------------构造函数
//--重写默认构造函数
vec() {
create();
}
//--带参构造函数
//对于只带有一个参数的构造函数,用户只能这样vec<int> a(100);来调用构造函数初始化,不能vec<int> a = 100;
//即explicit 消除了隐式转换
explicit vec(size_type n, const T& val = T()) {
create(n, val);
}
//--复制构造函数
vec(const vec &v) {
std::cout << "复制啦" << std::endl;
create(v.cbegin(), v.cend());
}
//--析构函数
~vec() {
uncreate();
}
//--------------------------------------重载操作符号
/*声明赋值操作符*/
vec& operator=(const vec&);//相当于vec<T>& vec<T>::operator=(const vec&);
/* 返回引用,1、方面调用a[i]=nums;来修改值2、避免经常复制,效率高*/
T& operator[](size_type i) {
return data[i];
}
const T& operator[](size_type i)const
{
return data[i];
}
//---------------------------------------迭代器(对系统指针进行改写)
iterator begin() { return data; }
iterator end() { return avail; }
const_iterator cbegin() const { return data; }
const_iterator cend()const { return avail; }
//---------------------------------------成员函数
/* 获取动态数组大小*/
size_type size()const { return avail - data; }
void push_back(const T& val)
{
if (avail == limit)//空间不足,重新申请空间
grow();
unchecked_append(val);//插入新元素
}
private:
iterator data;
iterator avail;
iterator limit;
std::allocator<T> alloc;
void create();
void create(size_type, const_reference);
void create(const_iterator, const_iterator);
void uncreate();
void grow();
void unchecked_append(const_reference);
};
/*赋值操作符实现*/
/*
* !!当用=为一个变量提供一个初始值时,调用的是复制构造函数(copy constructor):直接进行赋值
* !!当用=为一个变量进行赋值时,调用的是operator=函数:先删除先前的值,在进行赋值
*/
template <class T>
vec<T>& vec<T>::operator=(const vec<T> &rhs)
{
std::cout << "赋值啦" << std::endl;
//****检查是否自我赋值【若不判断,则会导致uncreate()销毁this本身的内容,若rhs=this,则rhs也被销毁了】
if (&rhs != this)//this类型是vec*,指向成员函数operator=操作的对象的指针
//this绑定在左操作数上
{
uncreate();//释放左值this数组内容
create(rhs.cbegin(), rhs.cend());//从右值复制给左值
}
return *this;
}
template <typename T>
void vec<T>::create()
{
data = avail = limit = nullptr;
}
template <typename T>
void vec<T>::create(size_type n, const_reference val)
{
data = alloc.allocate(n);//分配n个能够存放T的空间,并返回指向这块空间的首元素的指针
limit = avail = data + n;//均指向末尾
std::uninitialized_fill(data, limit, val);//初始化内存空间
}
template <typename T>
void vec<T>::create(const_iterator i, const_iterator j)
{
data = alloc.allocate(j - i);
limit = avail = std::uninitialized_copy(i, j, data);//初始化内存空间//返回最后一个复制赋值的下一个位置【按道理来讲应该是指向空】
}
template <typename T>
void vec<T>::uncreate()
{
if (data != nullptr)
{
iterator it = avail;
while (it != data)
alloc.destroy(--it);//先自减,再用alloc销毁it指向的内存块
alloc.deallocate(data, limit - data);//**deallocate()只能传入非空指针以及长度!!!
}
data = limit = avail = nullptr;
}
template <typename T>
void vec<T>::grow()
{
//两个指针相减的结果的类型为ptrdiff_t,它是一种有符号整数类型。
//减法运算的值为两个指针在内存中的距离(以数组元素的长度为单位,而非字节),
//因为减法运算的结果将除以数组元素类型的长度。所以该结果与数组中存储的元素的类型无关。
size_type new_size = std::max(2 * (limit - data), static_cast<ptrdiff_t>(1));
//申请更大(2倍)的内存空间
//将原先内容复制到新的内存空间
iterator new_data = alloc.allocate(new_size);
iterator new_avail = std::uninitialized_copy(data, avail, new_data);
//释放原先旧的内存空间
uncreate();
data = new_data;
avail = new_avail;
limit = new_data + new_size;
}
template <typename T>
void vec<T>::unchecked_append(const_reference val)
{
alloc.construct(avail, val);//将val值复制到avail所指的内存块中
++avail;
}
}
using namespace Ming;
int main()
{
vec<int> temp(2, 1);
temp.push_back(2);
temp.push_back(3);
temp.push_back(4);
for (auto i = temp.begin(); i != temp.end(); ++i)
std::cout << *i << std::endl;
vec<int> temp1 = temp; //复制构造函数
temp = temp1; //赋值构造函数
vec<int> temp2(10);
//vec<int> temp3 = 10;//只有一个参数的构造函数,有explicit则报错,无explicit则对
}