Question

I don't have a feeling (yet, I hope) for whether to chose value or reference semantics in some situations. Is there any rule of thumb I can apply?

I usually pick references for everything other than the built-in data types (char, int, bool, double etc.). However, sometimes it's not possible to return references from a function, so I would have to use pointers. The following function is an example of this:

Foo bar()
{
    Foo f;
    f.do_stuff();
    return f;
}

I'd use boost::shared_ptr to store the Foo object, but it makes working with the object quite ugly. I'm currently looking at a function that returns a deque that will hardly ever have more than 10 elements (that's what I assume, I have no way of making sure). Would it be OK to return this by value? Are my considerations a case of premature optimization?

Was it helpful?

Solution

Returning by value is fine, since most compilers will optimize the extra copy away (this is called Return Value Optimization, or rather Named Return Value Optimization in your case).

But the idiomatic way is

void bar(Foo& out)
{
   out.do_stuff();
}

OTHER TIPS

In any case, don't return anything allocated on the stack (i.e. local variable, such as f here) by reference or pointer.

You could always do this:

Foo& bar(Foo& f)
{
    f.do_stuff();
    return f;
}

And use it like this:

Foo f;
bar(f);

The drawback here is that you can't guarantee that bar() will receive a fresh copy of a Foo object. If that's important, you'll have to modify it to this:

Foo& bar(Foo& f)
{
    f = Foo();
    f.do_stuff();
    return f;
}

But then there will be an unnecessary initialization if it does get a fresh copy. Alternatively, you could simply examine f before doSomething() and throw an exception if it isn't up to expectations.

Use a reference when you want to maintain the state of any variable or object (i.e reurning the same variable to the calling routine after some procesisng has been done on the variable/object by the called routine) and also in case of passing large data to the function else there will be double copy of the large volumed data.

Also in some where copying of objects bit wise needs to be prevented, in such cases we make the copy constructor of a class as private.

My normal rules are:

  1. always use pass by value.

    Simple, eh? Reference suck. They should never have been introduced.

  2. If you have a "value like data structure" pass it. If you have an "object like data structure" pass a pointer (reference semantics, pass by value).

    It's usually clear what kind of thing a type is: value or object. If you can mutate it, its an object.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top