我很困惑下面的代码(对我来说令人惊讶):
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;
}
有人可以进一步启发我这种行为吗?
答案 0 :(得分:4)
对象不是左值或右值。单词 lvalue 和 rvalue 是表达式类别。它们将表达式分类,而不是对象分类。
对于该行:
returnsA() = anotherA;
由于=
的操作数是类类型,因此将搜索重载的运算符函数。 operator=
的特殊之处在于,如果用户未明确对其进行重载,则会生成默认的重载。该重载是具有签名的成员函数:
A& A::operator=(A const&);
并将调用returnsA() = anotherA;
转换为returnsA().operator=(anotherA);
,这是成员运算符重载的基本机制。
表达式returnsA()
的类别为 prvalue 。但是,最好在prvalue表达式上调用成员函数,因此这里没有问题。