【问题标题】:Calling Copy Constructor inside Assignment operator, lvalue required as left operand of assignment在赋值运算符中调用复制构造函数,需要左值作为赋值的左操作数
【发布时间】:2019-10-04 01:33:03
【问题描述】:

我试图在我的赋值运算符重载中调用我的复制构造函数。我将复制构造函数的结果分配给名为 temp 的指针,然后将 this 指针设置为等于 temp。这个结果给了我错误:左值需要作为赋值的左操作数。我认为这是指向我的对象的指针。为什么将指针重新分配给不同的对象会出现问题?

在传递的情况下,我尊重 this(*this) 并将其设置为等于 temp。对我来说,这意味着我说实际对象等于指针。我是不是误解了这个意思?

通过案例:

Foo *temp = new Foo(other); //invokes copy constructor
*this = temp;

失败案例:

Foo *temp = new Foo(other); //invokes copy constructor
this = temp;

完整源代码:

TreeNode::TreeNode(TreeNode *other) {
    this->leftChild = other->leftChild;
    this->rightChild = other->rightChild;
    this->data = other->data;
}

TreeNode& TreeNode::operator=(TreeNode *other) {
    if(this != other) {
        TreeNode *temp = new TreeNode(other);
        this = temp;
    }
    return *this;
}

【问题讨论】:

  • Proper 复制构造函数和复制赋值运算符不将指针作为输入,而是采用引用。而this是一个const指针,不能重新赋值
  • 对于TreeNode,您根本不需要编写复制构造函数和赋值运算符。编译器生成的就足够了。

标签: c++ oop constructor operator-overloading


【解决方案1】:

1) this 是每个类都有的内置右值表达式(意味着它不能按照 C++ 标准进行修改),它始终指向进行函数调用的类(对象)的实例。

2) *this 始终是一个左值,即它必须在内存中有一个地址,即它代表一个可以修改的对象。

所以当你取消引用这个时:

*this = temp

你有一个左值,与内存中的一个空间相关联,但不与

this = temp

关于右值和这个的详细讨论:

What is "rvalue reference for *this"?

Type of 'this' pointer

按原样,这段代码似乎有点问题。考虑当您执行以下操作时会发生什么:

treenode1 = treenode2;  //assuming both are pointers to TreeNode objects

编译器看到左值treenode1(在操作过程中总是指向它的对象'this'),然后看到'=',注意重载,然后使用指针treenode2创建对象treenode2指向的新副本到(将左值 temp 绑定到新对象),然后尝试将 temp 中的值复制到原始的 treenode1 绑定对象中(我相信我们现在存在三个 TreeNode)。

我相信你不希望在这个复杂的操作完成后让那个临时对象挂起,因为这会导致内存泄漏。所以你需要先删除它。因此,如果您出于某种原因绝对必须这样做,则解决方案是移动赋值运算符,该运算符专为与临时对象一起使用而设计。可能最好完全避免这种模式,但它似乎很容易导致内存泄漏。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-03
    • 2018-10-19
    • 1970-01-01
    相关资源
    最近更新 更多