问题
I'm currently learning C++, and am a bit confused about the concept of returning a reference from a method. Consider the following toy example:
#include <iostream>
#include <vector>
class IntHolder {
private:
std::vector<int> d_values;
public:
IntHolder() {
d_values.push_back(1);
d_values.push_back(2);
d_values.push_back(3);
}
std::vector<int> &values() {
return d_values;
}
};
int main(int argc, char **argv) {
IntHolder h;
std::vector<int> ret_val = h.values();
std::cout << ret_val.size() << std::endl;
ret_val.push_back(4);
ret_val.push_back(5);
std::cout << h.values().size() << std::endl;
return 0;
}
This prints the following to the standard output:
3
3
Since we are returning a reference to d_values, shouldn't the object returned be the same that is stored in the instance of IntHolder, and thus when calling h.values() again, we should see a size of 5?
Since this is not the case, what is the difference between returning a reference to an object or a copy of the object? Is there a difference when you are returning from a method?
回答1:
You are returning a reference from the values function, but you are not assigning that returned object to a reference variable. Instead, you are making a copy of it because you are assigning it to a new std::vector<int> named ret_val.
You want to modify your code like so, in order to capture the returned reference:
std::vector<int>& ret_val = h.values();
Or perhaps simply:
auto& ret_val = h.values();
回答2:
Your method is returning a reference, but you are then assigning the result to another vector, causing a copy. To fix this, change your ret_val definition to:
std::vector<int> & ret_val = h.values();
回答3:
If you return a reference, you return the same object and you are not creating a copy. Basically it seems that it is just as you did expect it:
std::cout << h.values().size() << std::endl;
h.values().push_back(4);
h.values().push_back(5);
std::cout << h.values().size() << std::endl;
Would return
3
5
The misstage is another one. Let's look at
std::vector<int> ret_val = h.values();
You discovered that ret_val is a copy of h.d_values while h.values() is returning a reference to it. We could rewrite your code above as follows:
std::vector<int> &ret_ref = h.values(); // object returned by `h.values()`
std::vector<int> ret_val = ret_ref;
If you are calling ret_ref.push_back(4), h.d_values would change. But ret_val is a copy of the returned object and will not affect h.d_values.
来源:https://stackoverflow.com/questions/38172818/returning-a-reference-vs-a-copy-from-a-c-method