假设我有赋值运算符,我的复制构造函数是 this = obj 好吗?
Assuming I have assignment operator, is my copy constructor being this = obj okay?
基本上,我的问题如下:假设我已经为 class 创建了一个赋值运算符,是否违反约定或不赞成让我的复制构造函数只是 this = item?
假设我正在创建一个仅包含以下数据的模板化 class:
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);
}
}
那如果我的拷贝构造函数简单如下会不会违convention/looked下upon/considered不正确?
template<class ItemType>
obj<ItemType>::obj(const obj & copyThis){
this = copyThis;
}
在复制构造函数中调用 operator=
通常是安全的(只要 operator=
不尝试将复制构造函数用作其逻辑的一部分)。
但是,您的 operator=
一开始就实施错误。它泄漏内存,不处理分配给自身的 this
,并且不 return 对 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
已经实现了复制语义)。
基本上,我的问题如下:假设我已经为 class 创建了一个赋值运算符,是否违反约定或不赞成让我的复制构造函数只是 this = item?
假设我正在创建一个仅包含以下数据的模板化 class:
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);
}
}
那如果我的拷贝构造函数简单如下会不会违convention/looked下upon/considered不正确?
template<class ItemType>
obj<ItemType>::obj(const obj & copyThis){
this = copyThis;
}
在复制构造函数中调用 operator=
通常是安全的(只要 operator=
不尝试将复制构造函数用作其逻辑的一部分)。
但是,您的 operator=
一开始就实施错误。它泄漏内存,不处理分配给自身的 this
,并且不 return 对 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
已经实现了复制语义)。