我无法使用STL和boost库,我必须用C++编写自己的容器.以下代码在VC++ 6中编译时没有错误.
我实际上没有测试过代码,但是关心这个通用容器是否适用于原始类型和非原始类型(如类).复制构造函数和赋值运算符是否会出现任何潜在问题?
欢迎任何其他建议和意见.:)
template <class T>
class __declspec(dllexport) StdVector{
private:
int _pos;
int _size;
const T *_items;
public:
StdVector();
StdVector(const StdVector &v);
StdVector(int size);
virtual ~StdVector();
void Add(const T &item);
void SetSize(int size);
int GetSize();
const T * Begin();
const T * End();
const T * ConstIterator();
StdVector & operator=(const StdVector &v);
};
template <typename T>
StdVector<T>::StdVector()
: _pos(0), _size(0), _items(NULL){
}
template <typename T>
StdVector<T>::StdVector(const StdVector &v)
: _pos(0), _size(v.GetSize()), _items(new T[_size]){
std::copy(v.Begin(), v.End(), Begin());
}
template <typename T>
StdVector<T>::StdVector(int size)
: _pos(0), _size(size), _items(new T[_size]){
}
template <typename T>
StdVector<T>::~StdVector(){
if (_items != NULL)
delete[] _items;
}
template <typename T>
void StdVector<T>::Add(const T &item){
if (_pos == _size)
throw new exception("Already at max size!!!");
_items[_pos++] = item;
}
template <typename T>
void StdVector<T>::SetSize(int size){
if (_items != NULL)
delete[] _items;
_pos = 0;
_size = size;
_items = new T[_size];
}
template <typename T>
int StdVector<T>::GetSize(){
return _size;
}
template <typename T>
const T * StdVector<T>::Begin(){
return _items;
}
template <typename T>
const T * StdVector<T>::End(){
return _items + _pos;
}
template <typename T>
const T * StdVector<T>::ConstIterator(){
return _items;
}
template <typename T>
StdVector<T> & StdVector<T>::operator=(const StdVector &v){
if (this != &v){
delete[] _items;
std::copy(v.Begin(), v.End(), Begin());
}
return *this;
}
Run Code Online (Sandbox Code Playgroud)
此默认值构造新对象并分配它们(或者,如果Begin()返回的T*不是const T*,请参见dribeas的回答),如果您使用原始存储并就地构造新对象,则效率可能更高。另外,作为GetSize(),Begin()而End()不是常量,他们不能在参数调用v。
template <typename T>
StdVector<T>::StdVector(const StdVector &v)
: _pos(0), _size(v.GetSize()), _items(new T[_size]){
std::copy(v.Begin(), v.End(), Begin());
}
Run Code Online (Sandbox Code Playgroud)
if语句是多余的。delete[]在NULL指针上就可以了。此外,是否有任何迹象表明它是虚拟的?看起来这不是旨在派生的类。
template <typename T>
StdVector<T>::~StdVector(){
if (_items != NULL)
delete[] _items;
}
Run Code Online (Sandbox Code Playgroud)
SetSize销毁所有对象并创建新对象。这可能是“令人惊讶的”行为。同样,如果new抛出该对象,则该对象将指向已释放的内存。同样,如果保护删除是多余的。
template <typename T>
void StdVector<T>::SetSize(int size){
if (_items != NULL)
delete[] _items;
_pos = 0;
_size = size;
_items = new T[_size];
}
Run Code Online (Sandbox Code Playgroud)
这有什么意义呢?它似乎与相同Begin。它甚至不是const方法。
template <typename T>
const T * StdVector<T>::ConstIterator(){
return _items;
}
Run Code Online (Sandbox Code Playgroud)
难道这不是_items刚刚删除的尝试副本(再次参见有关Begin()返回const T*和关于Begin()而End()不是const 的要点)吗?
template <typename T>
StdVector<T> & StdVector<T>::operator=(const StdVector &v){
if (this != &v){
delete[] _items;
std::copy(v.Begin(), v.End(), Begin());
}
return *this;
}
Run Code Online (Sandbox Code Playgroud)
这exception是什么班?std::exception没有采用的构造函数const char*。您还应该抛出异常对象,而不是动态分配的异常对象的指针。几乎不可能可靠地清除由指针“抛出”的动态分配的异常。
template <typename T>
void StdVector<T>::Add(const T &item){
if (_pos == _size)
throw new exception("Already at max size!!!");
_items[_pos++] = item;
}
Run Code Online (Sandbox Code Playgroud)
代码中有几件事.我仍然无法理解为什么在某些环境中禁止使用STL,当它经过彻底测试并且相当便宜时(包括STL或任何其他模板化代码,你只编译你使用的部件)......这迫使人们重新发明轮子等等通常情况下,它会以粗糙的角落结束.
我将开始讨论STL被禁止的原因,并试图找出之前允许的库(如果决定性能,请考虑STL的Electronic Arts版本,如果他们不信任VC6 STL实现,请考虑STLPort).在质量上开发接近STL的任何东西需要相当多的努力和知识.
现在到你的容器.首先,您要首先定义类要求,要对向量及其元素执行哪些操作.您的代码的限制是:
您的代码的一些特殊事项:
const T*,因此在构建后不能更改.explicit为了避免不必要的隐式转换.一些附注......你不允许使用STL,但你可以使用STL的std::copy一部分吗?STL的哪些部分超出限制?