Reputation: 23
I'm learning object oriented programming. I don't know about the difference between these codes. Both of them use return-by-reference, but Code#1 is working well but Code#2 isn't working well. Professor said Code #2 has a problem when I store the return value of swap function, it causes the problem. But I don't know why.
Please tell me why and the difference of two codes.
Code #1:
#include <iostream>
using namespace std;
struct Pair {
int first;
int second;
};
Pair& swap(Pair&);
int main()
{
Pair p1 = {10, 20};
Pair p2 = swap(p1);
return 0;
}
Pair& swap(Pair& pair)
{
int temp;
temp = pair.first;
pair.first = pair.second;
pair.second = temp;
return pair;
}
Code #2:
#include <iostream>
using namespace std;
struct Pair {
int first;
int second;
};
Pair& swap(int num1, int num2);
int main()
{
Pair p = swap(10, 20);
return 0;
}
Pair& swap(int num1, int num2)
{
int temp;
temp = num1;
num1 = num2;
num2 = temp;
Pair pair = {num1, num2};
return pair;
}
Upvotes: 1
Views: 78
Reputation: 25526
At very first, you can avoid unnecessary code:
int temp = num1;
num1 = num2;
num2 = temp;
Pair pair = {num1, num2};
Why swapping numbers first, just create the pair with numbers swapped:
Pair pair = {num2, num1};
// ^ ^
But now let's consider the differences (I dropped all parts irrelevant to the problem, i. e. the actual swapping):
Pair& swap(Pair& pair)
{
return pair;
}
In the first variant, you get a pair by reference. The pair must be created outside and is passed into the function:
Pair p; // created outside
swap(p); // swap uses reference to p outside
// p still exists
// swap returns just a reference to the same p it received
// -> you can use it for assignment:
Pair pp = swap(p);
Notice that your function swapped the original p it received by reference, so both p and pp contain the same content. So these two snippets of code are equivalent:
Pair p;
Pair pp = swap(p);
Pair p;
swap(p); // ignoring the return value
Pair pp = p;
In the second variant, you create the pair inside the function!
Pair& swap(int num1, int num2)
{
Pair pair = {num1, num2};
return pair;
}
But the pair's lifetime ends with the function exiting. So you return a reference to a pair that actually already has been destroyed, which yields undefined behaviour.
Exactly the same happens, if you accept the pair by value:
Pair& swap(Pair pair) // not a reference -> pair is copied into local variable
{
return pair; // returning reference to local -> undefined behaviour!
}
In all cases you want to return local variables, you need to return them by value:
Pair swap(int, int)
{
Pair pair;
return pair; // return by value, value will be copied into target variable
// (actually, due to copy elision, directly written there)
}
Returning by value can be useful, too, if you don't want to modify the pair passed to the function (just for completeness, it's not that you need to change your function to). You'd then make sure, though, that you won't modify the pair passed to. You could accept by const reference and create the copy inside; most simple way, though, is accepting by value, which creates the copy directly when receiving the paramter:
Pair swap(Pair pair) // notice: both references dropped
{
return pair;
};
Now, p and pp do differ (well, assuming you actually implemented the swapping, of course):
Pair p;
Pair pp = swap(p);
Upvotes: 1
Reputation: 1
in #code2 the Pair exist only in scope of swap function
in #code1 you need a temp becouse you change exist pair and you want to save the value before you change it. in #code2 (let's ignore about main problem) you need just form pair from the valus you got
Pair& swap(int num1, int num2)
{
Pair pair = {num1, num2};
return pair;
}
and if you think about it you don't swap pair becouse you haven't pair..
Upvotes: 0
Reputation: 425
The difference is that in Code #1, the main()
function declares the variable pair
, so it exists in the scope of main()
. In Code #2, the swap()
function declares the variable pair
so it exists only in the scope of the swap()
function and once you leave the swap function, the variable is destroyed.
Upvotes: 2