operator overloading using ostream and chaining. Why return by reference?

后端 未结 5 1104
粉色の甜心
粉色の甜心 2021-02-10 19:24

There are many questions and answers for this, but I can\'t really find why we need to return by reference.

If we have (assume operator is already correctly ov

5条回答
  •  一生所求
    2021-02-10 19:52

    Blah Blah::operator =(Blah rhs){
       Blah ret;
       ret.x = rhs.x;
       ret.y = rhs.y;
       return ret;
     }
      Blah b1(2,3);
      Blah b2(4,1);
      Blah b3(8,9);
      Blah b4(7,5);
      b3 = b4 = b2 = b1;
    

    b3 is going to take in b4 as its rhs, but you are not actually modifying the value of b3, you are making a new variable of the same type Blah and returning it to null (in this case null means nothing because there is nothing to the left of b3. Even if there was something to the left of b3, it would not make a difference as another Blah variable would do the same thing as b3 and b4 did.

    In fact if you had another class (say CoolClass that also has and x and y) and overloaded the assignment operator to take in a blah variable and have it actually modify the its own x and y you would find that.

    coolObject = b3 = b4 = b2 = b1; //CoolObject.x = 2, CoolObject.y = 3
    

    I'm still not exactly sure what your major complaint is with passing by reference. Here is how I would write that operator for Blah.

    Blah & Blah::operator = (const Blah & rhs) { x = rhs.x; y = rhs.y; return *this; }
    

    This guarantees that your rhs is non mutable and that chaining behavior works properly.

    If you are looking for better behavior with a different kind of object, say the ostream for instance, it can sometimes be helpful to declare a friend function. These are functions that you can declare in your new class, but don't belong to the class directly. The benefit of this approach is to have a operator that looks like it comes from ostream class, but it is in the Blah class instead. You can still use private and protected members inside a friend function which makes them useful.

    friend std::ostream & Blah::operator << (std::ostream & lhs, const Blah & rhs)
    { return lhs << "{" << rhs.x << ", " << rhs.y << "}"; }
    

    What this does is pass around the same ostream object and fills it with data in order of precedence. The exact same behavior you would expect to find with regular text and ostream.

    Using your first example you can think of it this way. Assuming obj1 and obj2 are both Blah, the cout object takes in obj1 via the friend function and returns the same cout object modified by the data in obj1, then the newly modified cout object takes in obj2 are returns the same modified cout object again, but now its also being modified by obj2 as well.

    (cout << obj1) << obj2;
    

提交回复
热议问题