Vector动态数组
相当复杂 情况很多
自定义一个动态扩容的数组
当分配的内存不足时 扩容 然后move旧内容 而不是copy
这样会节约一些性能和资源
#include<iostream>
#pragma once
template<typename T>
class Vector
{
public:
Vector()
{
ReAlloc(2);
}
~Vector()
{
delete[] m_Data;
}
void PushBack(const T& value)
{
if (m_Capacity <= m_Size) //放不下 扩容数组
{
ReAlloc(m_Capacity + m_Capacity / 2);
}
m_Data[m_Size] = value;
m_Size++;
}
void PushBack(T&& value)
{
if (m_Capacity <= m_Size) //放不下 扩容数组
{
ReAlloc(m_Capacity + m_Capacity / 2);
}
m_Data[m_Size] = std::move(value);
m_Size++;
}
template<typename... Args>
T& EmplaceBack(Args&&... args)
{
if (m_Capacity <= m_Size) //放不下 扩容数组
{
ReAlloc(m_Capacity + m_Capacity / 2);
}
new(&m_Data[m_Size]) T(std::forward<Args>(args)...); //在对应的位置构造
//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;
m_Data = nullptr;
}
const T& operator[](size_t index) const
{
if (index >= m_Size)
{
//assert
}
return m_Data[index];
}
T& operator[](size_t index)
{
return m_Data[index];
}
size_t Size() const
{
return m_Size;
}
private:
void ReAlloc(size_t newCapacity)
{
//1 分配一个新的内存块
T* newBlock = new T[newCapacity];
if (newCapacity < m_Size) //缩小数组的情况
m_Size = newCapacity;
//2 copy/move old elements into new block
for (size_t i = 0; i < m_Size; i++)
{
newBlock[i] = std::move(m_Data[i]); //不能使用memcpy 因为可能有的地方需要深拷贝 需要调用复制构造函数
}
//3 delete
delete[] m_Data;
m_Data = newBlock;
m_Capacity = newCapacity;
}
private:
T* m_Data = nullptr;
size_t m_Size = 0; //存储的数量
size_t m_Capacity = 0; //分配内存的个数
};
struct Vector3
{
float x = 0, y = 0, z = 0;
Vector3() {}
Vector3(float scale) :x(scale), y(scale), z(scale) {}
Vector3(float x, float y, float z) :x(x), y(y), z(z) {}
Vector3(const Vector3& other)
:x(other.x), y(other.y), z(other.z)
{
std::cout << "copy" << std::endl;
}
Vector3(Vector3&& other)
:x(other.x), y(other.y), z(other.z)
//: x(std::move(other.x)), y(std::move(other.y)), z(std::move(other.z))
{
std::cout << "move" << std::endl;
}
~Vector3()
{
std::cout << "Destory" << std::endl;
}
Vector3& operator=(const Vector3& other)
{
std::cout << "Copy\n";
x = other.x;
y = other.y;
y = other.y;
return *this;
}
Vector3& operator=(const Vector3&& other)
{
std::cout << "Move\n";
x = other.x;
y = other.y;
y = other.y;
return *this;
}
};
template<typename T>
void PrintVector(const Vector<T>& vector)
{
for (size_t i = 0; i < vector.Size(); i++)
{
std::cout << vector[i] << std::endl;
}
std::cout << "______________________________\n";
}
void PrintVector(const Vector<Vector3>& vector)
{
for (size_t i = 0; i < vector.Size(); i++)
{
std::cout << vector[i].x << "," << vector[i].y << "," << vector[i].z << std::endl;
}
std::cout << "______________________________\n";
}
int main()
{
Vector<Vector3> v;
//v.PushBack(std::move(Vector3(1)));
//v.PushBack(Vector3(2));
//v.PushBack(Vector3(3));
//v.PushBack(Vector3(1));
//v.PushBack(Vector3(5));
//v.PushBack(Vector3(1));
//v.PushBack(Vector3(3));
//v.PushBack(Vector3(4));
v.EmplaceBack(1, 2, 3);
v.EmplaceBack();
//PrintVector(v);
//v.EmplaceBack(2, 5, 8);
//PrintVector(v);
//v.PopBack();
//PrintVector(v);
//v.EmplaceBack(1, 1, 1);
//v.EmplaceBack(2, 5, 8);
//PrintVector(v);
//v.Clear();
PrintVector(v);
}