赋值重载:为什么使用同一个对象会导致程序出现问题?

Bob*_*ohn 0 c++

假设我们有以下内容:

class StringClass
{
public:
    ...
    void someProcessing( );
    ...
    StringClass& operator=(const StringClass& rtSide);
    ...
private:
    char *a;//Dynamic array for characters in the string
    int capacity;//size of dynamic array a
    int length;//Number of characters in a
};

StringClass& StringClass::operator=(const StringClass& rtSide)
{
    capacity = rtSide.capacity;
    length = rtSide.length;
    delete [] a;
    a = new char[capacity];

    for (int i = 0; i < length; i++)
       a[i] = rtSide.a[i];

    return *this;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:当我们尝试将对象分配给自己时,为什么重载赋值运算符的实现会导致问题,如:

StringClass s;
s = s;
Run Code Online (Sandbox Code Playgroud)

我正在阅读的教科书(绝对C++)说,在delete [] a;"指针sa未定义之后.赋值运算符已经破坏了对象,并且程序的运行可能已经毁了."

为什么操作员损坏了s?如果我们在删除它之后立即重新启动sa,为什么这会在程序中导致我们必须重新定义函数的问题:

StringClass& StringClass::operator=(const StringClass& rtSide)
{
    if (this == &rtSide)
    //if the right side is the same as the left side
    {
        return *this;
    }
    else
    {
        capacity = rtSide.capacity;
        length = rtSide.length;
        delete [] a;
        a = new char[capacity];
        for (int i = 0; i < length; i++)
            a[i] = rtSide.a[i];

        return *this;
    }
}
Run Code Online (Sandbox Code Playgroud)

Mat*_*lia 5

如果你要为一个对象分配一个对象art.a指向同一个字符串,那么当你这样做时,delete [] a你要删除所有art.a指向; 然后你重新分配它,但是你要在循环中复制(自身)的数据已经丢失了delete.

在循环中,您现在只需复制碰巧在其new自身返回的内存中发生的任何垃圾.

顺便说一句,即使使用自我分配检查的"安全网",赋值运算符也不完全正常(例如,它不是例外安全); 定义"三巨头"(复制构造函数,赋值运算符,析构函数)的"安全"方式是使用" 复制和交换习语 ".