这是为了更简单的替代std::vector,为娱乐而写的。它应该和std::vector一样快或者更快,但是不需要有那么多的特性。
它也应该简单易用。
我希望就以下各点作出检讨:
以下是头文件Vector.hpp
#pragma once
#include "../Types.hpp"
#include "../System/Memory/Memory.hpp"
namespace Core
{
namespace DataStruct
{
template<class ItemType> class Vector
{
ItemType* VecPtr;
UInt Capacity;
UInt Length;
void AllocSpace();
void DestroyAll();
public:
typedef ItemType* Iterator;
typedef ItemType const * ConstIterator;
Vector();
~Vector();
void Reserve(UInt Capacity);
void Add(ItemType const & Value);
void Insert(UInt Position, ItemType const & Value);
void Remove(UInt Position);
void Clear();
void Free();
UInt GetCapacity() const;
UInt GetLength() const;
ItemType operator[](UInt Position) const;
Iterator Begin();
Iterator End();
ConstIterator Begin() const;
ConstIterator End() const;
ConstIterator CBegin() const;
ConstIterator CEnd() const;
};
#include "Vector.cpp"
}
}以及实现Vector.cpp,它被排除在构建之外,并包含在Vector.hpp中,因为它是一个模板。
template <class ItemType> void Vector<ItemType>::AllocSpace()
{
if(Capacity == 0U)
Reserve(2U);
else if(Capacity == Length)
Reserve(Capacity << 1U);
}
template <class ItemType> void Vector<ItemType>::DestroyAll()
{
Iterator it = Begin();
Iterator end = End();
while(it < end)
it++->~ItemType();
}
template<class ItemType> Vector<ItemType>::Vector() : VecPtr(NULL), Capacity(0U), Length(0U) {}
template<class ItemType> Vector<ItemType>::~Vector()
{
Free();
}
template<class ItemType> void Vector<ItemType>::Reserve(UInt Capacity)
{
ItemType* ptr;
if(Capacity > this->Capacity)
{
ptr = (ItemType*)System::Memory::Alloc(sizeof(ItemType) * Capacity);
if(VecPtr)
{
System::Memory::Copy(VecPtr, ptr, sizeof(ItemType) * this->Capacity);
System::Memory::Free(VecPtr);
}
VecPtr = ptr;
this->Capacity = Capacity;
}
}
template<class ItemType> void Vector<ItemType>::Add(ItemType const & Value)
{
Insert(Length, Value);
}
template<class ItemType> void Vector<ItemType>::Insert(UInt Position, ItemType const & Value)
{
ItemType* ptr;
Bool insert;
AllocSpace();
//If Position is beyond the end then insert at end.
insert = Position < Length;
ptr = insert ? VecPtr + Position : VecPtr + Length;
if(insert)
System::Memory::Move(ptr, ptr + 1, sizeof(ItemType) * (Length - Position));
new((VoidPtr)ptr) ItemType(Value);
++Length;
}
template<class ItemType> void Vector<ItemType>::Remove(UInt Position)
{
ItemType* ptr;
if(Position < Length)
{
--Length;
ptr = VecPtr + Position;
ptr->~ItemType();
if(Position < Length)
System::Memory::Move(ptr + 1, ptr, sizeof(ItemType) * (Length - Position));
}
}
template<class ItemType> void Vector<ItemType>::Clear()
{
DestroyAll();
Length = 0U;
}
template<class ItemType> void Vector<ItemType>::Free()
{
if(VecPtr)
{
DestroyAll();
System::Memory::Free(VecPtr);
VecPtr = NULL;
Capacity = 0U;
Length = 0U;
}
}
template<class ItemType> UInt Vector<ItemType>::GetCapacity() const
{
return Capacity;
}
template<class ItemType> UInt Vector<ItemType>::GetLength() const
{
return Length;
}
template<class ItemType> ItemType Vector<ItemType>::operator[](UInt Position) const
{
return *(VecPtr + Position);
}
template<class ItemType> typename Vector<ItemType>::Iterator Vector<ItemType>::Begin()
{
return VecPtr;
}
template<class ItemType> typename Vector<ItemType>::Iterator Vector<ItemType>::End()
{
return VecPtr + Length;
}
template<class ItemType> typename Vector<ItemType>::ConstIterator Vector<ItemType>::Begin() const
{
return VecPtr;
}
template<class ItemType> typename Vector<ItemType>::ConstIterator Vector<ItemType>::End() const
{
return VecPtr + Length;
}
template<class ItemType> typename Vector<ItemType>::ConstIterator Vector<ItemType>::CBegin() const
{
return VecPtr;
}
template<class ItemType> typename Vector<ItemType>::ConstIterator Vector<ItemType>::CEnd() const
{
return VecPtr + Length;
}Memory命名空间中的函数调用以下内容:
Memory::Alloc -> mallocMemory::Copy -> memcpyMemory::Move -> memmoveMemory::Free -> free发布于 2013-01-07 20:42:42
Vector的第一个也是最明显的缺点是它不满足序列的标准需求。这意味着您的Vector不能与任何标准算法一起使用,也不能与设计用于处理序列的第三方算法一起使用。它只用于存储元素,而不是其他任何东西。
在每次使用Vector时,缺少适当的构造函数/析构函数和赋值操作符都会导致崩溃和泄漏。在这个主题上有很多话要说,请搜索一个基本的C++规则,称为“三的规则”,它将让您知道应该如何编写这些特殊的成员函数来实现正确的语义。
实现的下一个明显缺点是只能获得存储在Vector中的元素的副本。这不仅不方便,它还真的低效。必须复制元素的副本才能读取元素;要写入元素,必须复制、修改所述副本、从Vector中删除元素,然后插入修改后的副本。如前所述,这既不方便,也很低效。对于下标操作符来说,这将是一个更好的方法:
ItemType& operator[](UInt Position){ ... };
ItemType const& operator[](UInt Position) const{ ... };这将返回对存储元素的引用,因此,如果我们有一个非const Vector,就可以对其进行适当的修改。
另一个重要的缺点是,实现的Vector只适用于标准布局类型。简单地为任何其他类型移动或复制底层内存可能会导致内部值混淆、不变量中断、甚至崩溃和未定义的行为。
命名约定对C++来说是很奇怪的,它似乎是从一种不同的语言,也许是C#带来的。但是语义是不一样的,因此对于一个Vector编码器来说,这个C++看起来很奇怪,而对于一个倾向于认为语义来自C#的C#编码器来说,它似乎是很熟悉的。
您说过,这是为了更简单地替代std::vector。但是,如果我用std::vector替换Vector,代码甚至不会编译,即使会编译,观察到的行为也会有很大的不同。通常情况下,当您使用C++编写代码时,您应该遵守C++约定。这同样适用于任何其他语言。
https://codereview.stackexchange.com/questions/20243
复制相似问题