#include<iostream>
#include<string>
template<typename T>
class Vector {
private:
size_t m_Size = 0;
size_t m_Capacity = 0;
T* m_Data = nullptr;
public:
Vector() {
ReAlloc(2);
}
~Vector() {
//清除内置数据空间
//delete[] m_Data;
//方法里会手动调用清除元素对象的析构函数
clear();
//删除对象时,不会调用对象的析构函数,将对象的析构函数的调用全部在clear() 函数中统一处理
::operator delete(m_Data, m_Capacity * sizeof(T));
}
//添加数据
void PushBack(const T& value) {
if (m_Size >= m_Capacity)
ReAlloc(m_Capacity + m_Capacity / 2);
// = 操作符被删除时,此句不可用, 教学视频中可用,此处打问号❓️
//m_Data[m_Size] = value;
//自定义适配
m_Data[m_Size] = (T&&)value;
m_Size++;
}
//移动数据,不涉及到copy,注意:临时变量前面不能+ const
void PushBack(T&& value) {
if (m_Size >= m_Capacity)
ReAlloc(m_Capacity + m_Capacity / 2);
m_Data[m_Size++] = std::move(value);
}
//可变参数元素添加
template<typename... Args>
T& EmplaceBack(Args&&... args) {
if (m_Size >= m_Capacity) {
ReAlloc(m_Capacity + m_Capacity / 2);
}
//这个性能更优越,不会调用move= ! 和 Destroy !
new(&m_Data[m_Size]) T(std::forward<Args>(args)...);
//这个会调用一次:move= ! 和 Destroy !
//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;
}
size_t Size() const { return m_Size; }
const T& operator[] (size_t index) const {
if (index >= m_Size) {
//assert();
}
return m_Data[index];
}
T& operator[] (size_t index) {
if (index >= m_Size) {
//assert();
}
return m_Data[index];
}
private:
//重新分配内存,所以,无论新的size是 > < = ,都将reSize
void ReAlloc(size_t newCapacity) {
//1. allocate a new block of memory
//2. copy/move old block elements
//3. delete old elements
//T* newBlock = new T[newCapacity];
//
// 这里没必要调用构造函数,只需要分配空间即可。我们不用C语言的malloc (), 而是C++的 ::operator new
//创建对象时不会调用构造函数
T* newBlock = (T*)::operator new(newCapacity * sizeof(T));
//如果新的容量大小 < 现有数据大小,则将现有数据大小切小
if (newCapacity < m_Size)
m_Size = newCapacity;
//这里使用for loop 而不是memcopy是因为:我们需要用到复制构造函数,如果是原始数据类型,用memcopy OK,但是复杂类型:class, struct 则会导致深拷贝。
//而我们确认调用了那个copy structure (复制构造函数),否则复杂类型无法正确地复制构造。
for (size_t i = 0; i < m_Size; i++) {
newBlock[i] = std::move(m_Data[i]);
}
//delete[] m_Data;
//clear(); //不可用clear(), 因为此方法里将 m_Size 清零了
for (size_t i = 0; i < m_Size; i++)
m_Data[i].~T();
//::operator delete时不会调用对象的析构函数
::operator delete(m_Data, m_Capacity * sizeof(T));
m_Data = newBlock;
m_Capacity = newCapacity;
}
};
struct Vector3 {
public:
float x = 0.0f, y = 0.0f, z = 0.0f;
//指针类型数据,可能会导致Vector的delete出现问题
int* m_memoryBlock = nullptr;
Vector3() { m_memoryBlock = new int[5]; }
Vector3(float scalar) : x(scalar), y(scalar), z(scalar) { m_memoryBlock = new int[5]; }
Vector3(float x, float y, float z) : x(x), y(y), z(z) { m_memoryBlock = new int[5]; }
//Vector3(const Vector3& other) : x(other.x), y(other.y), z(other.z), m_memoryBlock(other.m_memoryBlock) {
// std::cout << "Copy ! \n";
//}
Vector3(const Vector3& other) = delete;
//删除复制构造函数,避免复制(m_memoryBlock时)
Vector3(Vector3&& other) : x(other.x), y(other.y), z(other.z) {
m_memoryBlock = other.m_memoryBlock;
other.m_memoryBlock = nullptr;
std::cout << "Move ! \n";
}
~Vector3() {
std::cout << "Destroy ! \n";
delete[] m_memoryBlock;
}
//Vector3& operator=(const Vector3& other) {
// std::cout << "Copy= ! \n";
// x = other.x;
// y = other.y;
// z = other.z;
// m_memoryBlock = other.m_memoryBlock;
// return *this;
//}
Vector3& operator=(const Vector3& other) = delete;
//删除复制赋符号函数,避免复制(m_memoryBlock时)
Vector3& operator=(Vector3&& other) {
std::cout << "move= ! \n";
x = other.x;
y = other.y;
z = other.z;
m_memoryBlock = other.m_memoryBlock;
other.m_memoryBlock = nullptr;
return *this;
}
};
void PrintVector3(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 << "----------------------------" << std::endl;
}
template<typename T>
void PrintVector(Vector<T>& vector) {
for (size_t i = 0; i < vector.Size(); i++) {
std::cout << vector[i] << std::endl;
}
std::cout << "----------------------------" << std::endl;
}
//1. 标准库基础类元素测试
void testStdType() {
Vector<std::string> vector;
vector.PushBack("Hello");
vector.PushBack("World");
vector.PushBack("Hello World");
PrintVector(vector);
}
//2. 自定义类构造函数
void testSelfDefineTypePushBack() {
Vector<Vector3> vector0;
vector0.PushBack(Vector3(1.2f));
vector0.PushBack(Vector3(1.2f, 2.3f, 3.4f));
vector0.PushBack(Vector3());
PrintVector3(vector0);
}
//3. 自定义类可变参数批量方式
void testSelfDefineTypeEmplaceBack() {
Vector<Vector3> vector1;
vector1.EmplaceBack(1.2f);
vector1.EmplaceBack(2, 3, 4);
vector1.EmplaceBack();
PrintVector3(vector1);
}
//4. 自定义类可变参数批量方式
void testSelfDefineTypePopBackClear() {
{
Vector<Vector3> vector3;
vector3.EmplaceBack(1.0f);
vector3.EmplaceBack(2, 3, 4);
vector3.EmplaceBack(1, 3, 4);
vector3.EmplaceBack();
PrintVector3(vector3);
vector3.PopBack();
vector3.PopBack();
vector3.EmplaceBack(5, 2, 0);
vector3.EmplaceBack(1, 7, 9);
PrintVector3(vector3);
vector3.clear();
PrintVector3(vector3);
vector3.EmplaceBack(5, 2, 0);
vector3.EmplaceBack(1, 7, 9);
PrintVector3(vector3);
}
}
int main() {
testSelfDefineTypePopBackClear();
std::cin.get();
}
wandbox验证