假设我有赋值运算符,我的复制构造函数是 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> &copyThis)
{
    if (this != &copyThis)
    {
        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> &copyThis)
{
    if (this != &copyThis)
    {
        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> &copyThis)
{
    if (this != &copyThis) {
        obj<ItemType>(copyThis).swap(*this); 
    }

    return *this;
}

也就是说,如果您用 std::vector 替换您的手动数组,那么您根本不需要手动实现复制构造函数或复制赋值运算符,编译器生成的默认值将足够了(因为 std::vector 已经实现了复制语义)。