-2

Pertaining to the this pointer, I wanted someone's opinion whether the below 2 snippets of code implement the same functionality or not.

Position Position::operator = (Position pos)
{
     this->x = pos.x;
     this->y = pos.y;
     return *this;
}

Position & Position::operator = (Position pos)
{
     this->x = pos.x;
     this->y = pos.y;
}

I know that the 1st snippet is more commonly used. However, I want to confirm if the 2nd snippet does the same functionality as I am passing a reference to the this object using &.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 3
    Uh, Code Snippet 2 has no return statement, and is undefined behavior. Any decent compiler will issue a warning or maybe even an error for that. – Mooing Duck May 15 '19 at 21:17
  • 1
    And even if you put missing `return *this` in code snippet 2, then something like `Position p1, p2; ...; (p2 = p1).x = 5;` will behave differently between the two snippets. – Daniel Schepler May 15 '19 at 21:22
  • 5
    The second snippet is better once obvious bug of not returning the value is fixed. – SergeyA May 15 '19 at 21:24
  • 1
    Both snippets are wrong. `operator=` must return `*this` by reference, so the 1st snippet is wrong because it returns `*this` by value instead, and the 2nd snippet is wrong because it does not `return` anything at all. The correct implementation should be more like this: `Position& Position::operator=(Position pos) { this->x = pos.x; this->y = pos.y; return *this; }` – Remy Lebeau May 15 '19 at 21:27
  • 2
    @RemyLebeau technically speaking, snippet 1 is not wrong (there is no requirement for assignment operator to return value by reference, or to return anything at all for this matter), it is just not idiomatic for multiple reasons. – SergeyA May 15 '19 at 21:31
  • @SergeyA see [Assignment operators](https://en.cppreference.com/w/cpp/language/operator_assignment) and [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/) – Remy Lebeau May 15 '19 at 21:33
  • Also, I think argument should be `(const Position& pos)` to avoid copying, that's more common. – Mirko May 16 '19 at 01:02
  • Isn't your link a clear duplicate? – SergeyA May 16 '19 at 13:08

1 Answers1

2

Pay attention to this post that @RemyLebeau mentioned before you choose the option that you want: What are the basic rules and idioms for operator overloading?

Example of differences between the two:

class Position1 {
public:
    int x, y;

    Position1 operator=(Position1 pos)
    {
        this->x = pos.x;
        this->y = pos.y;
        return *this;
    }
};

class Position2 {
public:
    int x, y;

    Position2& operator=(Position2 pos)
    {
        this->x = pos.x;
        this->y = pos.y;
        return *this;
    }
};

int main() {
    Position1 p11, p12;
    Position2 p21, p22;

    //Position1 *p13 = &(p12 = p11); // Compilation error: Taking address of temporary object..
    p21.y = 20;
    p21.x = 10;
    Position2 *p23 = &(p22 = p21); // Working - the `temporary object` is a reference to non temporary object.
    p23->x = 99;
    p23->y = 84;
    cout << p21.x << " " << p21.y; // didn't change
    cout << p22.x << " " << p22.y; // changed
    cout << p23->x << " " << p23->y; // changed

    //===================================================

    //(p12 = p11).y = 3; // Compiling error: Expression is not assignable
    (p22 = p21).y = 3; // works
    cout << p21.x << " " << p21.y << endl; // didn't change
    cout << p22.x << " " << p22.y << endl; // changed

    return 0;
}
Coral Kashri
  • 3,436
  • 2
  • 10
  • 22