临时C ++对象是左值吗?

时间:2018-09-25 04:19:32

标签: c++

我很困惑下面的代码(对我来说令人惊讶):

class A {
  int a=0;
};

A returnsA(void)
{
  static A myA;

  return myA;
}

void works(void)
{
  A anotherA;

  returnsA() = anotherA;
}

我在标准或网络上找不到任何内容,表明不应进行编译。在我看来,这很奇怪。

我猜returnsA()返回一个对象(myA的副本),因此我们在其上调用默认的副本分配操作符,anotherA被复制分配给返回的对象,然后超出范围并被破坏。

我原本希望这种行为无法编译:

int returnsint(void)
{
  static int i=0;

  return i;
}

void doesntwork(void)
{
  int anotherint=0;

  returnsint() = anotherint;
}

有人可以进一步启发我这种行为吗?

1 个答案:

答案 0 :(得分:4)

对象不是左值或右值。单词 lvalue rvalue 表达式类别。它们将表达式分类,而不是对象分类。


对于该行:

returnsA() = anotherA;

由于=的操作数是类类型,因此将搜索重载的运算符函数。 operator=的特殊之处在于,如果用户未明确对其进行重载,则会生成默认的重载。该重载是具有签名的成员函数:

A& A::operator=(A const&);

并将调用returnsA() = anotherA;转换为returnsA().operator=(anotherA);,这是成员运算符重载的基本机制。

表达式returnsA()的类别为 prvalue 。但是,最好在prvalue表达式上调用成员函数,因此这里没有问题。


如果您想阻止班级接受此类作业,请see here。以及为什么默认赋值运算符不能那样工作的原因,see here