基本上,我的问题如下:假设我已经为一个类创建了一个赋值运算符,它是违反约定还是不赞成让我的拷贝构造函数只是这个= item?
让我们说我只使用以下数据创建模板化的类:
private:
int _size;
ItemType* _array;
如果我的赋值运算符如下:
template<class ItemType>
void obj<ItemType>::operator = (const obj & copyThis){
_size = copyThis.getSize();
_array = new ItemType[_size];
for (int i = 0; i < _size; i++){
//assuming getItemAt is a function that returns whatever is in given location of object's _array
_array[i] = copyThis.getItemAt(i);
}
}
那么如果我的复制构造函数如下,是否会违反惯例/看不起/认为不正确?
template<class ItemType>
obj<ItemType>::obj(const obj & copyThis){
this = copyThis;
}
答案 0 :(得分:1)
在复制构造函数中调用operator=
通常是安全的(只要operator=
不尝试将复制构造函数用作其逻辑的一部分)。
但是,您的operator=
实施错误。它会泄漏内存,不会处理分配给自身的this
,也不会返回对this
的引用。
请改为尝试:
template<class ItemType>
obj<ItemType>::obj(const obj & copyThis)
: _size(0), _array(0)
{
*this = copyThis;
}
template<class ItemType>
obj<ItemType>& obj<ItemType>::operator=(const obj<ItemType> ©This)
{
if (this != ©This)
{
int newSize = copyThis.getSize();
ItemType *newArray = new ItemType[newSize];
// consider using std::copy() instead:
//
// std::copy(copyThis._array, copyThis._array + newSize, newArray);
//
for (int i = 0; i < newSize; ++i) {
newArray[i] = copyThis.getItemAt(i);
}
delete[] _array;
_array = newArray;
_size = newSize;
}
return *this;
}
话虽这么说,通常使用复制构造函数实现operator=
通常更好,而不是相反:
template<class ItemType>
obj<ItemType>::obj(const obj & copyThis)
: _size(copyThis.getSize()), _array(new ItemType[_size])
{
for (int i = 0; i < _size; ++i){
_array[i] = copyThis.getItemAt(i);
}
// or:
// std::copy(copyThis._array, copyThis._array + _size, _array);
}
template<class ItemType>
obj<ItemType>& obj<ItemType>::operator=(const obj<ItemType> ©This)
{
if (this != ©This)
{
obj<ItemType> tmp(copyThis);
std::swap(_array, tmp._array);
std::swap(_size, tmp._size);
}
return *this;
}
如果添加swap
方法,可以稍微清理一下:
template<class ItemType>
obj<ItemType>::obj(const obj & copyThis)
: _size(copyThis.getSize()), _array(new ItemType[_size])
{
for (int i = 0; i < _size; ++i){
_array[i] = copyThis.getItemAt(i);
}
}
template<class ItemType>
void obj<ItemType>::swap(obj<ItemType> &swapThis)
{
std::swap(_array, swapThis._array);
std::swap(_size, swapThis._size);
}
template<class ItemType>
obj<ItemType>& obj<ItemType>::operator=(const obj<ItemType> ©This)
{
if (this != ©This) {
obj<ItemType>(copyThis).swap(*this);
}
return *this;
}
话虽这么说,如果用std::vector
替换手动数组,那么根本不需要手动实现复制构造函数或复制赋值运算符,编译器生成的默认运算符将会足够(因为std::vector
已经实现了复制语义)。