FrostyStraw
FrostyStraw

Reputation: 1656

Passing object by reference vs by value in overload functions

I keep reading that when doing overload operator functions, it's best to pass by reference, usually for performance reasons. But I notice that when I pass the object by value, it still has the same effect. Shouldn't passing it by value NOT affect the operator? I know that if you have two int variables and you wanna swap them by passing them to another function, it'll only work if you pass by reference (or if you pass a pointer). If you just passed the value, the variables remain unchanged at the end. So shouldn't the same apply to passing class objects?

Example:

Person Person::operator+(Person obj1){
    Person sum;
    sum.age = this->age + obj1.age;

    return sum;
} 

if I have a main and do:

Person person1(14);
Person person2(182);
Person3 = person1 + person2;
std::cout << person3.age << std::endl;

It does the same as if I had done

Person Person::operator+(Person &obj1){
    Person sum;
    sum.age = this->age + obj1.age;

    return sum;
} 

So I was sort of thinking of this like in the swap method I mentioned. If I pass the value to a swap function, it won't change the original values of the variables. I was thinking that if I just passed the object instead of a reference, it wouldn't change actually overload the operator. Now I'm thinking that since in my Person class, both the operator and the variables are defined in the same class, then the same doesn't apply and that's why it actually does overload the operator?

Upvotes: 2

Views: 665

Answers (1)

Xornand
Xornand

Reputation: 190

Both the operator+ overloads you have defined return a Person object with age value of 196 (which is what I except your output should be). Neither method makes any attempt to modify the values that are passed in (one via the implicit this pointer). I have tried to illustrate why via comments directly in each of your methods below.

In the first operator+:

Person Person::operator+(Person obj1){

    // We have access to Person1 via the implicit this pointer.
    // obj1 is a copy of Person2. Hence, we have no access to Person2.

    Person sum;

    // The next statement only reads from the 2 objects.
    sum.age = this->age + obj1.age;

    // New object returned without any side effects to Person1 or Person2.
    return sum;
}

In the second operator+:

Person Person::operator+(Person &obj1){
    // We have access to Person1 via the implicit this pointer.
    // We have access to Person2 by obj1.

    Person sum;

    // The next statement only reads from the 2 objects.
    sum.age = this->age + obj1.age;

    // New object returned without any side effects to Person1 or Person2.
    return sum;
}

You can prove this to yourself by modifying the two method signatures as such:

Person Person::operator+(Person obj1) const
Person Person::operator+(const Person &obj1) const

Now both methods are disallowed from modifying the values being added.

The swap example you gave regarding needing to pass by reference or by pointer to get the swap to work is such because swap has to modify the objects that are being swapped. In the Person example, the operator+ only needs to return a new Person object which has the correct values gotten from adding two Person objects.

In your example, you should prefer passing by const reference because it will skip the overhead to copy Person2 (as it had to in the first method). This answer would change a bit if you needed to copy the passed in parameter in the body of the method. But here you don't.

Upvotes: 0

Related Questions