我不能使用STL和boost库,我必须用C++编写我自己的容器。下面的代码在VC++6中编译时没有错误。
我并没有实际测试过代码,但是我担心这个泛型容器是否可以同时使用原始类型和非原始类型(如class)。特别是复制构造函数和赋值操作符会有什么潜在的问题吗?
我们非常欢迎任何其他的建议和意见。:)
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;
}发布于 2009-11-28 19:22:31
默认情况下会构造新对象并分配它们(或者,如果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());
}if语句是多余的。空指针上的delete[]就可以了。另外,它是虚拟的有什么意义吗?它看起来不像是一个被设计为派生的类。
template <typename T>
StdVector<T>::~StdVector(){
if (_items != NULL)
delete[] _items;
}SetSize将销毁所有对象并创建新对象。这可能是“令人惊讶”的行为。此外,如果new抛出,对象将指向已释放的内存。同样,保护删除的if也是多余的。
template <typename T>
void StdVector<T>::SetSize(int size){
if (_items != NULL)
delete[] _items;
_pos = 0;
_size = size;
_items = new T[_size];
}这有什么意义呢?它似乎和Begin做同样的事情。它甚至不是const方法。
template <typename T>
const T * StdVector<T>::ConstIterator(){
return _items;
}这个尝试不会复制到刚刚被删除的_items (再次参见关于Begin()返回const T*和关于Begin()和End()不是常量的要点)?
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;
}这是什么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;
}发布于 2009-11-28 19:44:08
代码中有几件事。我仍然不能理解为什么在一些环境中使用STL是被禁止的,因为它是经过全面测试的,而且相当便宜(当包含STL或任何其他模板代码时,您只编译您使用的部分)……这迫使人们重新发明轮子,往往以粗糙的弯道告终。
我会开始讨论为什么禁止STL,并尝试制定一个以前允许的库(如果是性能方面的决定,请考虑电子艺界版本的STL,如果他们不信任VC6 STL实现,则考虑STLPort )。开发在质量上接近STL的任何东西都需要相当多的努力和知识。
现在来看看你的容器。首先,您需要定义您的类需求,以及要对向量及其元素执行哪些操作。你的代码的限制是:
你的代码中有一些特殊的东西:
construction.
const T*的,因此在construction.
以避免不需要的隐式构造函数,并且返回迭代器的方法应为常量。
一些附注。你不能使用STL,但你可以使用STL中的std::copy?STL的哪些部分超出了限制?
发布于 2009-11-28 19:18:58
以下是一些简短的说明:
在std::copy statement
额外的好处:你可能想看看Stepanov的lecture notes。前几章是关于向量类的设计。
https://stackoverflow.com/questions/1812259
复制相似问题