Reputation: 11
I'm learning Objecct Oriented Programming in C++. I have some doubts about the following code:
class Vehicle
{
protected:
string license ; int year ;
public:
Vehicle(const string &myLicense, const int myYear) : license(myLicense), year(myYear){}
const string getDesc() const
{
return license + " from " + stringify(year);
}
const string &getLicense() const {return license;}
const int getYear() const {return year;}
};
what does it mean to use the reference operator (&) for the return value of a function. Why is it convenient to use? I think that the result is exactly the same and you use the same ammount of memory whether or not you use the (&) in the getlicense function.
why does this code use the reserved word const? I see it can work withusing using it. is there any advantage of using const in the code?
Thanks in advance for your help folks.
Upvotes: 1
Views: 163
Reputation: 490178
Returning a reference can avoid a copy as others have already pointed out. I feel obliged to point out, however, that there's usually more to the story than that.
First of all, returning a reference to a local object generally leads to problems. Therefore, when you return a reference, you generally need to be doing one of two things:
return *this;
).I'd go so far as to say that in most cases, the lack of copying (or at least the efficiency gained from lack of copying) involved is a more or a sideline than the primary reason you return a reference. In the case of an iostream, you're returning a reference primarily because an iostream is basically an "identity" kind of object -- i.e., you can't copy or assign one. You create one, use references to that one, sole object, and when you're done you destroy it.
When you pass a reference to an object, the primary intent is often to eliminate a copy. When you return a reference, however, that's much less often the case.
I'd also note that for quite a while now most compilers have implemented Return Value Optimization and Named Return Value Optimization (RVO/NRVO). This means returning a value often won't lose any efficiency compared to returning a reference in any case (in fact, what'll happen is the compiler will internally turn your code that returns a value into code that receives a reference, and writes directly to the parent's value).
Bottom line: returning a reference isn't quite as simple or obvious as it may initially seem. Outside of the handful of situations where it's routine (insertion, extraction, and assignment operators being the most obvious) it's something you probably really need to think about and know what you're doing, not just a simple, obvious optimization.
Upvotes: 0
Reputation: 361482
It is used to avoid unecessary copy when returning the object, although it depends on the call-site as well, as at the call-site one can make a copy, and may not make a copy:
std::string copy = veh.getLicence(); //makes a copy
const std::string & notAcopy = veh.getLicence(); //does not make a copy
//and most importantly here
size_t size = veh.getLicense().size(); //doesn't make a copy!
Returning a reference particularly helps in chained function calls. In chained function calls, if you do not want to call a function on a copy, then you've to return by reference, so that you can ensure that the chained function call is on the original object, just like in the third example above.
There are some classes whose return type has to be reference type (or pointer type), otherwise it wouldn't work because their copy-constructors has been disabled by declaring them private
. The most frequently used such classes are IOStream classes, e.g std::istream
,std::ostream
and all classes deriving from them. In such cases, you've to use std::ostream&
as return type of a function (usually these functions are operator<<
overloads).
Upvotes: 2
Reputation: 27248
When you have const string &getLicense() const {return license;}
, it means that you return the license value by reference. Without the &
you will return by value. Quoting:
When a variable is returned by reference, a reference to the variable is passed back to the caller. The caller can then use this reference to continue modifying the variable, which can be useful at times. Return by reference is also fast, which can be useful when returning structs and classes.
Now, without the const
, the caller would be able to modify the value of your license
member value, and according to the code you don't want this to happen.
So, to summarize, &
is used in order to return by reference, which is faster than return by value (because you just return a reference and you don't copy an object), and const
is used in order to forbid the modification.
You can read more about return-by-reference here, on C++-FAQ-lite.
Upvotes: 1
Reputation: 9662
Please format your code better! That is unnecessarily hard to parse:
class Vehicle
{
public:
Vehicle(const string & myLicense, const int myYear)
: license(myLicense)
, year(myYear)
{}
const string getDesc() const
{
return license + " from " + stringify(year);
}
const string & getLicense() const {return license;}
const int getYear() const {return year;}
protected:
// good convention: put details that users shouldn't be paying attention to
// below the public parts that they *should* be paying attention to
string license;
int year;
};
Returning a const string &
means you're giving read-only (const) access to the outside world to directly interact (by reference) with this object's license (because that's what getLicense() does).
Usually that's an efficiency option. i.e. you could return license by value (copy), but then you're copying the contents of license. This way you're simply giving direct access, but stipulating it is read-only.
const on the return indicates it's read-only nature. const on the end of a method declaration means that you're stating that this method won't alter the value of this object.
The latter is especially important if the caller has a const instance of Vehicle. The caller will not be allowed to call non-const methods, because they only have read-only access to their instance of a Vehicle.
Upvotes: 0
Reputation: 1356
By returning a reference to license you save a copy operation which would incur a memory allocation. By making it a const reference it prevents callers from modifying internal state.
Upvotes: 2