If I have a class that has many int
, float
, and enum
member variables, is it considered efficient and/or good practice to return them as references rather than copies, and return constant references where no changes should be made? Or is there a reason I should return them as copies?
views:
165answers:
6There is no reason to return primitive types such as int
and float
by reference, unless you want to allow them to be changed. Returning them by reference is actually less efficient because it saves nothing (int
s and pointers are usually the same size) while the dereferencing actually adds overhead.
This is probably mostly a matter of style or preference. One reason to not return references is because you are using getters and setters to allow you to change the implementation of those members, If you changed a private member to another type, or removed it completely because it can be computed, then you no longer have the ability to return a reference, since there's nothing to reference.
On the other hand, returning references for non-trivial types (compound classes) can speed up your code a bit over making a copy, and you can allow those members to be assigned through the returned reference (if desired).
If they are constant references, maybe it is OK. If they are not constant references, probably not.
As to efficiency - on a 64-bit machine, the references will be 64-bit quantities (pointers in disguise); int
and float
and enum
will be smaller. If you return a reference, you are forcing a level of indirection; it is less efficient.
So, especially for built-in types as return values, it is generally better to return the value rather than a reference.
Some cases it is necessary:
Look at overloaded operator[]
for any class. It usually has two versions. The mutating version has to return a reference.
int &operator[](int index); // by reference
int operator[](int index) const; // by value
In general, It is OK to allow access to class members by trusted entities by a class e.g. friends. In case these trusted entities also need to modify the state, references or pointers to the class members, are the only options one has.
In many cases, references usually simplify syntax e.g where 'v' is STL vector.
v.at(1) = 2 vs *(v.at(1)) = 2;
Almost, const references are better. For ints and such theres no point because you would want them to be changed or because they are the same size (or nearly) as a reference.
So yes it is a good idea. I prefer another language or to hack away at my own C++ stuff and just allow the var to be public (once again it just my own stuff)
This is a performance question mostly but from a robustness point of view I would say it's preferably to return values instead of const references. The reason being that even const references weakens encapsulation. Consider this:
struct SomeClass
{
std::vector<int> const & SomeInts () const;
void AddAnInt (int i); // Adds an integer to the vector of ints.
private:
std::vector<int> m_someInts;
};
bool ShouldIAddThisInt(int i);
void F (SomeClass & sc)
{
auto someInts = sc.SomeInts ();
auto end = someInts.end ();
for (auto iter = someInts.begin (); iter != end; ++iter)
{
if (ShouldIAddThisInt(*iter))
{
// oops invalidates the iterators
sc.AddAnInt (*iter);
}
}
}
So in case it makes semantically sense and we can avoid excessive dynamic allocations I prefer return by value.