赋值运算符在不应该返回时返回“空”实例?

Assignment operator is returning an "empty" instance when it shouldn't?

提问人:jscherman 提问时间:8/26/2016 最后编辑:songyuanyaojscherman 更新时间:8/26/2016 访问量:64

问:

我正在实现一个堆栈只是为了练习。所以,总的来说,我有这样的东西:

Stack stack;
stack.push(element1;
stack.push(element2);

Stack copy;
copy = stack;

所以我重载赋值运算符,因为我也想生成新的元素实例(而不仅仅是将每个元素的指针从一个元素复制到另一个元素),如下所示

Stack &Stack::operator=(const Stack &toCopy) {
    Stack* stack = new Stack;
    if (toCopy.first == NULL) return *stack;
    for (Node* actual = toCopy.first; actual != NULL; actual = actual->sig) {
        stack->push(actual->elem);
    }
    // In this state, *stack has 2 elements as it should
    return *stack;
}

回到主目录,复制变量没有得到更改......它仍然是空的,就好像分配从未发生过一样。好像我做了一样,你能解释一下这里面发生了什么吗?Stack copy;

C++ 指针 引用 重载 赋值运算符

评论

0赞 jscherman 8/26/2016
为什么投反对票?
2赞 M.M 8/26/2016
听起来你对内存管理有一些基本的误解。您的内存泄漏(永远不会是 d)。此外,它从不更新,而是更新新堆栈,从不对新堆栈执行任何操作。代码的其他部分可能有很多错误是你没有发布的。将来发布 MCVE,如果您停止使用原始指针,生活会变得轻松得多。operator=new Stackdelete*this
2赞 Ry- 8/26/2016
您可能应该在 中修改,而不是返回新堆栈。thisoperator=
1赞 PaulMcKenzie 8/26/2016
您的 operator= 应该更改并返回对 的引用,而不是创建一个新对象并返回它。thisthis
0赞 jscherman 8/26/2016
我现在明白了。谢谢大家!

答:

3赞 songyuanyao 8/26/2016 #1

您没有修改当前对象(即 )。*this

您只是通过 创建一个新对象,然后返回它。注意 ,它等效于 ,请注意,返回的值不会被使用,它只是被丢弃(并导致内存泄漏),并且不会更改。newcopy = stack;copy.operator=(stack);copy

您应该执行以下操作:

Stack &Stack::operator=(const Stack &toCopy) {

    // do some work to clear current elements in *this
    // ...

    // add elements from toCopy
    for (Node* actual = toCopy.first; actual != NULL; actual = actual->sig) {
        this->push(actual->elem);
    }

    // operator= is supposed to return *this in general
    return *this;
}
2赞 StoneThrow 8/26/2016 #2

您可能误解了赋值运算符。它在等号左侧对象的上下文中工作。因此,您应该始终努力工作,并且也应该始终返回。::operator=(...)*this*this

您发布的对象正在对堆上分配的新 Stack 对象进行操作,并且您正在对该对象进行操作,而不是对 .operator=(...)*this

您可以在代码中有效地替换为 。即:stackthis

Stack &Stack::operator=(const Stack &toCopy) {
    //Stack* stack = new Stack; // Don't do this.
    if (toCopy.first == NULL) return *this;
    for (Node* actual = toCopy.first; actual != NULL; actual = actual->sig) {
        this->push(actual->elem); // You could also just call push without "this->"
    }
    // In this state, *stack has 2 elements as it should
    return *this;
}