Return a const reference or a copy in a getter function?

前端 未结 8 1473
暗喜
暗喜 2020-12-12 20:50

What\'s better as default, to return a copy (1) or a reference (2) from a getter function?

class foo {
public:
    std::string str () { // (1)
              


        
相关标签:
8条回答
  • 2020-12-12 21:11

    The only problem I have with returning a const-reference, which is something I would typically do for non basic types, is that there is nothing to stop the caller removing the "const"ness and then modifying the value.

    Personally, I'd suggest that such code is a bug. If they know you're returning a reference and continue to cast away the const then it's on their head.

    0 讨论(0)
  • 2020-12-12 21:12

    I'm returning a reference, because a string seems not "cheap to copy" to me. It's a complex data type with dynamic memory management and all that.

    The "if you want the caller to get a copy, you should return by value" argument is moot, because it doesn't preclude copies at all. The caller can still do the following and get a copy anyway

    string s = obj.str();
    

    You need to explicitly create a reference on the caller side to be able to refer to the data member directly afterwards - but why would you do that? There definitely are enough user defined types that are cheap to copy

    • Smart Pointers
    • Iterators
    • All of the non-class types.
    0 讨论(0)
  • 2020-12-12 21:16

    If there is no special reason to use a value type as return value, I always return a const reference. If I need (or expect to need) a (writable) copy, I add a copy ctor and an assignment operator to the returned class if not already available. For the usage think of:

    const MyClass & ref = container.GetAt( 1234 ); // need only reference
    MyClass copy = container.GetAt( 1234 ); // get writable copy 
    

    Actually this is quite straight forward, isn't it?

    0 讨论(0)
  • 2020-12-12 21:21

    Well it really depends on what you expect the behaviour to be, by default.

    Do you expect the caller to see changes made to str_ unbeknownst(what a word!) to them? Then you need to pass back a reference. Might be good if you can have a refcounted data member and return that.

    If you expect the caller to get a copy, do 1).

    0 讨论(0)
  • 2020-12-12 21:23

    The compiler will not be able to perform (N)RVO in this case. The (named) return value optimization is an optimization where the compiler creates the function auto variables in the place of the return value to avoid having to copy:

    std::string f()
    {
       std::string result;
       //...
       return result;
    }
    

    When the compiler sees the code above (and assuming that if any other return is present it will also return the result variable) it knows that the variable result has as only possible fate being copied over the returned temporary and then destroyed. The compiler can then remove the result variable altogether and use the return temporary as the only variable. I insist: the compiler does not remove the return temporary, it removes the local function variable. The return temporary is required to fulfill the compilers call convention.

    When you are returning a member of your class, the member must exist, and the call convention requires the returned object to be in a particular location (stack address usually). The compiler cannot create the method attribute over the returned object location, nor can it elide making the copy.

    0 讨论(0)
  • 2020-12-12 21:34
    1. if its a small basic type - primatives like int and long and their wrappers and other basic things like 'Point' - return a copy

    2. if its a string, or any other complex type - return a reference.

    0 讨论(0)
提交回复
热议问题