Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning a const reference to an object instead of a copy

Tags:

c++

constants

Whilst refactoring some code I came across some getter methods that returns a std::string. Something like this for example:

class foo { private:     std::string name_; public:     std::string name()     {         return name_;     } }; 

Surely the getter would be better returning a const std::string&? The current method is returning a copy which isn't as efficient. Would returning a const reference instead cause any problems?

like image 291
Rob Avatar asked Sep 25 '08 17:09

Rob


People also ask

How do I return a const reference?

You want to return a const reference when you return a property of an object, that you want not to be modified out-side of it. For example: when your object has a name, you can make following method const std::string& get_name(){ return name; }; . Which is most optimal way.

Does const reference make a copy?

Not just a copy; it is also a const copy. So you cannot modify it, invoke any non-const members from it, or pass it as a non-const parameter to any function. If you want a modifiable copy, lose the const decl on protos .

What does it mean to return a reference to an object?

It means you return by reference, which is, at least in this case, probably not desired. It basically means the returned value is an alias to whatever you returned from the function. Unless it's a persistent object it's illegal.

Can a const function return a reference?

Then, no, you can't do that; in a const method you have a const this pointer (in your case it would be a const Foo * ), which means that any reference you can get to its fields1 will be a const reference, since you're accessing them through a " const path".


1 Answers

The only way this can cause a problem is if the caller stores the reference, rather than copy the string, and tries to use it after the object is destroyed. Like this:

foo *pFoo = new foo; const std::string &myName = pFoo->getName(); delete pFoo; cout << myName;  // error! dangling reference 

However, since your existing function returns a copy, then you would not break any of the existing code.

Edit: Modern C++ (i. e. C++11 and up) supports Return Value Optimization, so returning things by value is no longer frowned upon. One should still be mindful of returning extremely large objects by value, but in most cases it should be ok.

like image 122
Dima Avatar answered Oct 12 '22 08:10

Dima