【问题标题】:lvalue required as left operand of assignment for operator overloading需要左值作为运算符重载的赋值的左操作数
【发布时间】:2015-02-19 05:36:03
【问题描述】:

我正在尝试进行运算符重载,但当我从 .cpp 运行此代码时不断收到错误

头文件原型是这样的,

const Velocity & operator = (const Velocity & rhs);

.cpp 成员函数看起来像这样。

const Velocity & Velocity :: operator = (const Velocity & rhs)
{
   this->getDx() = rhs.getDx();
   this->getDy() = rhs.getDy();
   this->getX() = rhs.getX();
   this->getX() = rhs.getY();
   return *this;
}

在 main 中使用运算符的地方是这样的。

Velocity v1;
Velocity v2;
Velocity v3;

promptVelocity("Enter values for Velocity 1", v1);
promptVelocity("Enter values for Velocity 2", v2);

// Test operator =
v3 = v1;
cout << "Test operator = : " << v3 << endl;

我得到了这个->行的错误

lvalue required as left operand of assignment

请帮忙!

【问题讨论】:

  • 可分配的吸气剂是……奇怪,而且可能不正确。你不认为你应该向我们展示他们的声明吗?此外,返回 const 引用的赋值运算符很奇怪......您是否试图防止类似 (x=y)=z 的东西?似乎没有必要。
  • 首先 - 我们正在猜测您的吸气剂实现。其次,您应该为您的问题创建一个最小的工作示例。第三,您为什么认为使用 getter 方法设置值是个好主意?

标签: c++ operator-overloading member-functions


【解决方案1】:

将您的功能更改为:

Velocity& Velocity::operator=(const Velocity& rhs) {
  dx_ = rhs.getDx();
  dy_  = rhs.getDy();
  x_ = rhs.getX();
  y_ = rhs.getY();
  return *this;
}

...假设“dx_”、“dy_”等是实际变量的名称。赋值的左侧必须是一个“左值”(简单地定义它 - 一个带有地址的命名变量),而在您使用“右值”之前(作为结果返回的临时变量相应的“get”函数)。为了更详细地介绍这一点,很可能您的各种“get”函数返回值类型的对象(例如“int”)或 const 引用(例如“const int&”),但是要分配给某些东西,您确实需要一个可变引用(例如“int&”)。分配给返回简单值类型的“get”函数的输出是没有意义的,因为 get 函数所做的是在返回之前创建底层数据的 副本。虽然这个副本可能有一个与之关联的内存地址(例如,如果它存储在堆栈中),但分配给它不会产生可观察到的效果,因为除非分配它,否则这个副本不会做任何事情或在任何地方看到到某个变量。但是,当您在左侧使用成员变量的名称时,赋值实际上是有意义的,因为接收赋值的变量仍然可以在其他地方引用。

我还应该注意,在我的更改中,我删除了一堆多余的this-&gt;es。只有两种情况this-&gt; 是绝对必要的:

  1. 有一个同名符号“遮盖”this 的成员(例如,比类范围更窄的参数或其他局部变量),在这种情况下,有必要使用this-&gt; 选择成员而不是本地成员。

  2. 非常不精确:涉及template,因此有必要显式使用this-&gt; 以使C++ 在此类而不是命名空间范围内(请参阅dependent name lookup 以获得更精确的解释)。

在没有这两种情况的情况下,符号查找将正确找到没有this-&gt; 的成员变量,因此它是多余的,因此应该避免(在我看来)。

此外,我将赋值的返回类型从“const Velocity&”更改为“Velocity&”,因为赋值运算符通常返回所分配对象的可变实例,否则可能会令人惊讶;例如,使函数返回一个 const 中断:

Velocity velocity = // ...
Velocity default_vaue = // ...
// ... many lines later ...
if (/* some condition /*) {
  ReassignIfInvalid(velocity = ComputeSomething(), default_value);
}

... 其中函数“ReassignIfInvalid”要求参数是可变的,以便它可以有条件地覆盖该值。虽然上面的代码可能不是最好的模拟代码,但如果赋值的输出是不可变的,这将证明是令人惊讶的。

【讨论】:

  • 无论返回的引用是否为 const,链式赋值都能正常工作。返回非常量 ref 有充分的理由,但让 x = y = z 工作并不是其中之一。
  • @T.C.我忘了加上括号。无论如何,链式调用可变操作的必要性这一点仍然存在。
  • 我们真的关心(x=y)=z 案子吗?谁在编写该代码?
  • @MichaelAaronSafyan 我可以访问 dx 和 dy 变量,但 x 和 y 变量是私有的。为了分配它们,我是否必须为它们使用我的 get 函数?
  • @gman54,不,你不需要使用“get”函数……一个类可以访问它自己的“私有”变量。
【解决方案2】:

在 .cpp 函数中,您是在告诉 getter 函数应该从另一个函数获取值,因此您实际上并没有做某事。如果有,请使用 setter 函数。尽管你最好公开你的价值观,而不是使用 getter 和 setter。

【讨论】:

  • 我会公开变量,但赋值调用私有变量
  • 不要公开变量,使用settter方法
  • 但是使用 getter 和 setter 方法几乎就像是一个公共变量,不是吗?
猜你喜欢
  • 1970-01-01
  • 2013-08-21
  • 2011-09-03
  • 2018-10-19
  • 1970-01-01
相关资源
最近更新 更多