为什么在仍然通过时需要返回* this?

时间:2014-10-13 09:47:48

标签: c++ class operator-overloading assignment-operator

我写了下面的类,它重载了赋值运算符。如示例所示,我从赋值运算符返回*this

class Sample
{
    int *p;
    int q;

public:

    Sample()
    {
        cout<<"Constructor called"<<endl;

        p = new int;
        q = 0;
    }


    Sample& Sample::operator =(const Sample &rhs)
    {
        cout<<"Assignment Operator"<<endl;

        if(this != &rhs)
        {
            delete p;

            p = new int;
            *p = *(rhs.p);
        }

        return *this;
    }

    void display()
    {

        cout<<"p = "<<p<<"     q = "<<q<<endl;
    }
};

当我调用a = b之类的赋值运算符时,它就像a.operator=(b);一样。

现在我正在调用一个运算符函数,这已经与operator =一起传递,那么为什么需要从赋值运算符返回它呢?

4 个答案:

答案 0 :(得分:6)

如果要支持分配链接,则必须返回* this(以及引用)。例如

Class A
{
};

A x,y,z,w;
x = y = z = w; //For this you are returning *this.

编辑更多澄清: - (回应您的评论)

假设您没有从您的赋值运算符返回任何内容,那么表达式将按如下方式进行评估: -

x=y=z  =>   x=(y=z)

以上将导致对

的调用
y.operator(z)

因为赋值运算符是右关联的。 接下来的电话会是

x.operator ( value returned from y=z) ).

如果你没有返回任何值,链接就会失败。

希望我很清楚

答案 1 :(得分:1)

你将它返回以允许链接,你不能在不返回对Sample的引用的情况下链接赋值序列,也许这会使它更清晰:

int count = 0;

class Sample {
    int *p;
    int q;
    int m_count;
public:
    Sample() {
        m_count = count;
        cout<<"Constructor called for m_count = "<< count++ << endl;

        p = new int;
        q = 0;
    }

    Sample& operator =(const Sample &rhs) {
        cout<<"Assignment Operator (m_count " << 
                    m_count << " = m_count " << rhs.m_count << ") " <<endl;
        if(this != &rhs)
        {
            delete p; // Unnecessary
            p = new int; // Unnecessary
            *p = *(rhs.p);
        }
        return *this;
    }
};
int main() {
  Sample a;
  Sample b;
  Sample c;

  // [b = c] will return a Sample& to the "changed" b
  a = b = c;
}

Example

具有void返回值的反例:

int count = 0;
class Sample {
    int *p;
    int q;
    int m_count;
public:

    Sample() {
        m_count = count;
        cout<<"Constructor called for m_count = "<< count++ << endl;

        p = new int;
        q = 0;
    }

    void operator =(const Sample &rhs) {
        cout<<"Assignment Operator (m_count " << 
                    m_count << " = m_count " << rhs.m_count << ") " <<endl;

        if(this != &rhs) {
            delete p; // Unnecessary
            p = new int; // Unnecessary
            *p = *(rhs.p);
        }
    }
};

int main() {
  Sample a;
  Sample b;
  Sample c;

  a = b; // Valid
  a = b = c; // Not valid - error: no viable overloaded '='
}

答案 2 :(得分:1)

转让声明,

a = b;

要求b应为R值,a必须为L值。将分配更改为:

a=foo();

表达式foo(),即对foo的函数调用必须产生R值。如果foo返回void,则它不会产生R值(或任何值)。因此,foo需要返回一个值(通过显式return语句)。这是语言的使命!

第一个语句中的b也可能是L值。例如:

a = b = c;

变量b既是L值(对于b=c),也是R值(对于a=b)。当operator=返回T&时,它可以充当L值(以及R值)。但是当operator=返回const T&时,它可能只是R值。因此,如果一个类返回const引用,则以下不会工作:

a = b = c; 

此处,c已分配给a(在重载本身中),但bconst(仅限R值)。它不会允许a=b

答案 3 :(得分:0)

主要是支持分配链。

Sample A,B,C;
A=B=C;

You can have a look into the existing questions:

Why should the assignment operator return a reference to the object?

Why must the copy assignment operator return a reference/const reference?