views:

348

answers:

8

Given the following scenario, which one of the following is preferred. m_state is a member rater than a local variable.

class C
{
private:
    double m_state;
public:
    double state() const { return m_state; } // returns double
    double& state() { return m_state; }
}

===========================================

class C
{
private:
    double m_state;
public:
    const double& state() const { return m_state; } // returns const double&
    double& state() { return m_state; }
}
A: 

Are you trying to do a property like structure? If so, why don't you use getState() and setState(...)?

Daniel A. White
Why? That's 3 extra letters, along with inconsistency. I think overloading them is much more common.
GMan
+6  A: 

I wouldn't do this:

double& state() { return m_state; }

You may as well make m_state public if you did that. Probably what makes the most sense is:

const double & state() const { return m_state; }

Then again, when you're talking about saving the copy of a 64 bit variable (ie micro-optimization) and the fact that the latter version can be recast to whatever you want, I would just copy it:

double state() const { return m_state; }

(not that there's any true security anyway)

cletus
You should make the functions in your two last code snippets const. Other than that, good explanation.
Mads Elvheim
@Mads: quite right about the const this on the last two. Fixed. Thanks.
cletus
I don't think this answers the question... s/he's is asking specifically whether it's "better" to return a const reference or value.
Inverse
It completely answers the question. cletus describes why you should not return the address of a private member, thus the answer in this case considering the information we have is to return a copy.
Ed Swangren
You can't tell from the made-up sample the motivation. It is also not true that you should never return a reference (see what your `vector::operator[]` returns). Sometimes the things in the class conceptually belong to the caller, so they have a right to a reference.
UncleBens
Yes, few things are absolute. But again, the OP did not mention anything that would make us think that returning a refernce was the right thing to do.
Ed Swangren
doulbe }is not IDENTICAL to a public m_state.If you take const correctness seriously, the difference is crucial.With public m_state, the following code will compile!void dosomething(const C}
lyxera
+1  A: 

For something like a double just doing double state() const { ... } would be fine, the copy is fast, you and the caller don't need to worry about whether the return value can be modified, and it can be called from a const or non-const reference to the object.

For something more complex like an object it really depends on if you want to the caller to be able to modify it, perhaps you want them to be able to call non-const members if they are getting an object. If so then MyClass & state() const { ... } is your best bet.

joshperry
A: 

I would argue that the second version is preferred:

const double& state() const { return m_state; } // returns const double&

simply because it's consistent with how you would write this type of function if the return value was more complex. In your case, neither version would be any faster or safer than the other anyway.

Inverse
+1  A: 

It makes more sense to just return a double. Because you're not returning a reference to a more complex object. This is likely to be done in registers so it'll be marginally faster. If you really want to return a reference then make it a const const.

Rule of thumb is, simple types just return them. Objects - by reference. Anything else is needless complexity.

Matt H
A: 

The other answers have addressed the readability and code hygene implications of either approach.

As far as performance on the modern x86 archs is concerned, if the function is inline, it makes no difference either way. If the function is not inline, there is a tiny advantage to returning double rather than const double &, because the double just gets returned on a register, whereas the reference returns a pointer which must then be loaded through. But the one cycle cost of that is totally swamped by the penalty of having a non-inline function.

Crashworks
A: 

My suggestions :

Never return handle to the private data members of the class by public interface to make sure that client cant't modify it.

Check out effective C++ topic on it by scott mayers.

Ashish
A: 

Rule of thumb:

  • built-in (int, double, pointer) -> value
  • user-defined -> const reference

The following caveat applies: if you know what a POD (Plain Old Data) is, and you have one with a reasonable size, you can return it by value.

Matthieu M.