0

First, I am using as reference this excellent answer on this and *this.

Say I have a class:

class myclass{
    
    myclass& dosomething(){
        // do something here
        return *this;  //According to the referenced answer I am returning the same object
    }
    
    myclass& operator<<(myclass &mc){
        return mc;   // HERE, am I returning the same object??
    }    
};

int main(){
    myclass myobject;
    myobject << myobject.dosomething();    
}

My question is, in the overload operator, I am passing a reference as aan argument, right? And I am returning the same object, is this correct?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
KansaiRobot
  • 7,564
  • 11
  • 71
  • 150
  • 1
    If `x` and `y` are both `myclass`, do you want `x << y` to evaluate to `x` or `y`? – François Andrieux Oct 07 '21 at 15:12
  • 1
    `myclass myobject();` here you're defining `myobject` to be a function that takes no arguments and returns a `myclass`. You want to do this instead: `myclass myobject;` – Kevin Oct 07 '21 at 15:13
  • @Kevin corrected thanks – KansaiRobot Oct 07 '21 at 15:14
  • `myclass& myclass::operator<<(myclass &mc)` could be written as free operator: `myclass& operator<<(myclass& mcL, myclass& mcR)`. As you have implemented the former, the latter would have to do `return mcR;`. (With the former doing `return *this` instead, the latter had to `return mcL;`.) – Scheff's Cat Oct 07 '21 at 15:15
  • Does this answer your question? [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) – Richard Critten Oct 07 '21 at 16:30
  • @FrançoisAndrieux I think `y` – KansaiRobot Oct 08 '21 at 01:20

1 Answers1

2

You are returning the same reference that is passed as parameter. This is ok-ish, but only if thats what you want. For method chaining you typically do return *this.

Consider the following to see the difference:

#include <cstdlib>
#include <ctime>
#include <iostream>

struct myclass {
   int value;
   myclass& operator<<(myclass &mc) {
       std::cout << value << " << " << mc.value << "\n";
       return mc;
   }

   myclass& operator>>(myclass& mc){
       std::cout << value << " >> " << mc.value << "\n";
       return *this;
   }

};

int main(){
     myclass m1{1},m2{2},m3{3};
     m1 << m2 << m3;
     std::cout << "\n";
     m1 >> m2 >> m3;
}

Output:

1 << 2
2 << 3

1 >> 2
1 >> 3

Maybe it also helps to realize that the two lines can also be written as:

 m1.operator<<(m2).operator<<(m3);
 m1.operator>>(m2).operator>>(m3);

Usually one expects that m1 >> m2 >> m3; resolves to chained calls on m1, ie first m1 >> m2 then m1 >> m3.

Only when it is clear from context and semantics of myclass you should make m1 << m2 << m3; call first m1 << m2 and then m2 << m3.

Operator overloading is very permissive, you can do very weird things if you like, but it might lead to surprises when the user expects your operator<< to chain as usual.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185