C++ 11特性<Vector>基础容器实现,包含迭代器实现!(备注:代码里面包含很多新奇地方,切勿乱动,否则内存问题,后果自负)
template<typename Vector>
class VectorIterator
{
public:
using ValueType = typename Vector::ValueType;
using PointerType = ValueType*;
using ReferenceType = ValueType&;
public:
VectorIterator(PointerType ptr)
:m_ptr(ptr) {};
VectorIterator& operator++()
{
m_ptr++;
return *this;
}
VectorIterator& operator++(int)
{
VectorIterator iterator = *this;
++(*this);
return iterator;
}
VectorIterator& operator--()
{
m_ptr--;
return *this;
}
VectorIterator& operator--(int)
{
VectorIterator iterator = *this;
--(*this);
return iterator;
}
ReferenceType operator[](int index)
{
return *(m_ptr + index);
}
PointerType operator->()
{
return m_ptr;
}
ReferenceType operator*()
{
return *m_ptr;
}
bool operator ==(const VectorIterator& other) const
{
return m_ptr == other.m_ptr;
}
bool operator !=(const VectorIterator& other) const
{
return !(*this == other);
}
//~VectorIterator();
private:
PointerType m_ptr;
};
template<typename T>
class Vector
{
public:
Vector()
{ //初始分配2个元素
ReAlloc(2);
}
~Vector()
{
cout << "~VECTOR" << endl;
Clear();
//delete[] m_Data;
::operator delete(m_Data, m_Capacity * sizeof(T));
};
public:
using ValueType = T;
using Iterator = VectorIterator<Vector<T>>;
Iterator Begin()
{
return Iterator(m_Data);
}
Iterator End()
{
return Iterator(m_Data + m_Size);
}
public:
void PushBack(const T& value) //push_back 实现
{
if (m_Size >= m_Capacity) //内存不够的情况下
{
ReAlloc(m_Capacity+m_Capacity/2); //扩容百分之50
}
/*m_Data[m_Size] = value;
m_Size++;*/
::new(&m_Data[m_Size++]) T(value);
// ::new((void*)m_Size++)
}
void PushBack(const T&& value) //push_back 实现 如果你有(move)移动构造函数的情况下
{
if (m_Size >= m_Capacity) //内存不够的情况下
{
ReAlloc(m_Capacity + m_Capacity / 2); //扩容百分之50
}
/* m_Data[m_Size] = std::move(value);
m_Size++;*/
::new(&m_Data[m_Size++]) T(value);
}
template<typename... Args>
T& EmplaceBack(Args&&... args)
{
if (m_Size >= m_Capacity)
{
ReAlloc(m_Capacity + m_Capacity / 2);
}
//m_Data[m_Size] = T(std::forward<Args>(args)...); //右值引用 完美转发
new(&m_Data[m_Size]) T(std::forward<Args>(args)...);
return m_Data[m_Size++];
}
void PopBack()
{
if (m_Size > 0)
{
m_Size--;
m_Data[m_Size].~T();
}
}
void Clear()
{
for (size_t i = 0; i < m_Size; i++)
{
m_Data[i].~T();
m_Size = 0;
}
}
const T& operator[](size_t index) const //下标访问操作符
{
//assert(index > m_Size, "Size is too large");
//cout << "访问越界" << index << endl;
return m_Data[index];
}
T operator[](size_t index) 下标访问操作符可修改数据
{
if (index > m_Size)
{
cout << "访问越界" << index << endl;
return 0;
}
return m_Data[index];
}
size_t Size() const { return m_Size; }
private:
void ReAlloc(size_t newCapactiy) //内部扩容
{
//1. 分配一个新的内存块
//2. 拷贝所以元素 or move 移动所以元素到新内存块中
//3. 删除旧内存块.
//重载new方法 不在调用任何构造函数
//T* newBlock = nullptr;
T* newBlock = (T*)::operator new (newCapactiy * sizeof(T));
PrintMemoryUsage();
//T* newBlock = new T[newCapactiy];
if (newCapactiy < m_Size) //缩小内存情况下,更新内存新大小,防止溢出
{
m_Size = newCapactiy;
}
for (size_t i = 0; i < m_Size; i++)
//{
//*memcopy只适用在简单数据类型,这里需要访问类拷贝构造函数
//move偷即将销毁原内存,如果没实现move操作,会什么都不做
//字符串情况下,访问报错,构造函数没有初始化。
new (&newBlock[i]) T(std::move(m_Data[i]));
newBlock[i] = std::move(m_Data[i]);
// newBlock[i] = m_Data[i];
// }
for (size_t i = 0; i < m_Size; i++) //释放原内存
{
m_Data[i].~T();
}
::operator delete(m_Data, m_Capacity * sizeof(T));
//delete[]m_Data;
m_Data = newBlock; //替换新指针
m_Capacity = newCapactiy;//确保内存容量一致
}
private:
T* m_Data = nullptr; //储存类型
size_t m_Size = 0; //元素个数
size_t m_Capacity = 0; //实际内存大小
};
int main()
{
Vector<int> data;
data.PushBack(1.0123f);
data.PushBack(2.25f);
data.PushBack(3.21f);
data.PushBack(4.f);
data.PushBack(5.54f);
data.PushBack(6.8f);
for (Vector<int>::Iterator it = data.Begin(); it != data.End(); it++)
{
cout << "Iterator" << endl;
cout << *it << " " << " ";
}
cout << "\n";
data.Clear();
//** 在使用字符串情况下 PushBack无法使用 已解决
Vector<std::string> str;
str.PushBack("VectorString");
str.PushBack("is");
str.PushBack("Vector");
str.PushBack("Hello");
str.PushBack("china");
str.PushBack("Jpan");
str.EmplaceBack("USA");
str.EmplaceBack("牛批");
cout << "Vector Iterator 迭代器实现" << "\n";
for (Vector<string>::Iterator it = str.Begin(); it != str.End(); it++)
{
cout << *it <<" " <<" " ;
}
cout <<"\n";
};