关于重载赋值运算符的结果是否为左值的混淆 我有点怀疑,从《Visual C++ 2013》一书中读到这段:

关于重载赋值运算符的结果是否为左值的混淆 我有点怀疑,从《Visual C++ 2013》一书中读到这段:,c++,c++11,c++03,C++,C++11,C++03,将剩余的赋值操作表示为显式 重载函数调用,最终会变成: (motto1.operator=(motto2)).operator=(motto3); 现在,有一种情况,对象从 operator=()函数用于调用operator=()函数。如果 返回类型只是CMessage,这是不合法的,因为 原始对象的临时副本将返回,这将是一个 rvalue,并且编译器将不允许使用 右值。确保这一点的唯一方法是正确编译和工作 是返回一个引用,它是一个左值 类CMessage的定义如下: class CMessa

将剩余的赋值操作表示为显式 重载函数调用,最终会变成:

(motto1.operator=(motto2)).operator=(motto3);
现在,有一种情况,对象从
operator=()
函数用于调用
operator=()
函数。如果 返回类型只是
CMessage
,这是不合法的,因为 原始对象的临时副本将返回,这将是一个 rvalue,并且编译器将不允许使用 右值。确保这一点的唯一方法是正确编译和工作 是返回一个引用,它是一个左值

CMessage
的定义如下:

class CMessage
{
private:
    char* pmessage;

public:
    void ShowIt() const
    {
        cout << endl << pmessage;
    }

    CMessage(const char* text = "Default message")
    {
        cout << endl << "Constructor called.";
        pmessage = new char[strlen(text) + 1];
        strcpy(pmessage, text);
    }

    CMessage(const CMessage& initM)
    {
        cout << "Copy constructor called" << endl;
        pmessage = new char[strlen(initM.pmessage) + 1];
        strcpy(pmessage, initM.pmessage);
    }

    ~CMessage()
    {
        cout << "Destructor called." << endl;
        delete[] pmessage;
    }

    CMessage operator=(const CMessage& aMess)
    {
        delete[] pmessage;
        pmessage = new char[strlen(aMess.pmessage) + 1];
        strcpy(this->pmessage, aMess.pmessage);
        return *this;
    }
};
问:运算符函数是否真的返回右值,或者书中对该语句的理解是简单错误的

我的理解是,代码是有缺陷的,因为在最终结果中,
motto1
不会被更改,但除此之外,它是完全合法的,因为返回的副本(涉及副本构造函数)是左值

运算符函数是否真的返回一个右值,或者书中对该语句的理解是简单错误的

是的,这个特定的重载运算符确实返回值,因此调用表达式的值类别是(p)右值。这本书是对的

我的理解是代码是有缺陷的,因为在最终结果中,motto1不会被更改

如果目的是将
motto3
分配给
motto1
,那么是的,代码确实存在缺陷。然而,这本书给出的理由是:

编译器不允许使用右值调用成员函数

事实并非如此。对于C,可能是C++的标准版本,但对于标准C++,

不是正确的。 运算符函数是否真的返回一个右值,或者书中对该语句的理解是简单错误的

是的,这个特定的重载运算符确实返回值,因此调用表达式的值类别是(p)右值。这本书是对的

我的理解是代码是有缺陷的,因为在最终结果中,motto1不会被更改

如果目的是将
motto3
分配给
motto1
,那么是的,代码确实存在缺陷。然而,这本书给出的理由是:

编译器不允许使用右值调用成员函数

事实并非如此。对于C,可能是C++的标准版本,但对于标准C++来说,它不是真的。

< P> <代码> CMASCONTROR= =(const cMea/Aess)< /C> >按值返回。这意味着将返回一个临时对象,
(motto1=motto2)
的值类别为prvalue。请注意,
操作符=
在这里没有什么特别之处,对于任何按值返回的函数都是一样的

我的理解是,代码是有缺陷的,因为最终的结果是,motto1不会被更改,但除此之外,它是完全合法的

<>在ISO C++中,这是真的…< /P> 因为返回的副本(涉及副本构造函数)是左值

返回的副本是一个临时对象。“左值”一词是一个价值范畴的表达;它不是一个适用于物体的形容词。由函数调用组成的表达式的值类别,其中该函数按值返回是prvalue,而不是lvalue

编译器不允许使用右值调用成员函数。

在ISO C++中,将成员函数调用到rValk上是很好的。我不能和Visual C++ 2013对话。

< P> <代码> cMeMask=(const cMea/Aess)< /C> >按值返回。这意味着将返回一个临时对象,
(motto1=motto2)
的值类别为prvalue。请注意,
操作符=
在这里没有什么特别之处,对于任何按值返回的函数都是一样的

我的理解是,代码是有缺陷的,因为最终的结果是,motto1不会被更改,但除此之外,它是完全合法的

<>在ISO C++中,这是真的…< /P> 因为返回的副本(涉及副本构造函数)是左值

返回的副本是一个临时对象。“左值”一词是一个价值范畴的表达;它不是一个适用于物体的形容词。由函数调用组成的表达式的值类别,其中该函数按值返回是prvalue,而不是lvalue

编译器不允许使用右值调用成员函数。


在ISO C++中,将成员函数调用到rValk上是很好的。我不能用Visual C++ 2013来说话。

注释:页面包含了描述文本中的许多基本错误(虽然代码示例是OK),但我建议不要理会它。更好的是,我确认代码在VS 2013/2015下编译良好。感谢您提供有关MSDN和链接的建议。注意:该页面在描述性文本中包含许多基本错误(尽管代码示例没有问题),我建议您忽略它。更好的是,我确认代码在VS 2013/2015下编译良好。感谢您提供有关MSDN和链接的建议。相关问题:相关问题:
int main()
{
    CMessage motto1, motto2;
    CMessage motto3("A miss is as good as a mile.");

    (motto1 = motto2) = motto3;

    motto1.ShowIt();
    motto2.ShowIt();
    motto3.ShowIt();
}