简体   繁体   中英

When should I return by T const&?

When should I return by T const& ? If I am not going to modify the object, I do not see how it is any different from returning by value. And returning by const reference really just means no copy is made. So when is returning by T const& useful.

There are two reasons why you would prefer to return by const& rather than by value.

The first is semantics. A code which returns something by const& is telling the caller explicitly , "here is a read-only version of what you asked for. If you want to store it permanently, or make changes to it, you are responsible for making a copy of it." The semantics of this return type are quite clear, and easily enforced.

The second is optimization. By returning something by-value, you remove some optimization opportunities from the compiler. That is not to say that returning by-value is less efficient than returning by const& (in fact, in cases the opposite might be true -- consider a function that returns a char on a 64-bit system). It simply means you remove one of the tools from the compiler's optimization toolbox. There is another tool there to replace it -- namely, inlining the call along with copy elision -- so this might be a wash. It all depends on context.

I mention "semantics" as the first reason because I consider it to be the most important. There are so many variables with optimization and so many moving parts that it's often hard to know just what optimizations the compiler will be able to employ and when. One thing is certian all the time however -- clear semantics are more easily understood by humans than muddled semantics.

A common case where you'd return const T& is a const getter member function:

T& get() { return m_some_private_member; }

const T& get() const { return m_some_private_member; }

In this case you often don't want to make a copy - you just want to return a reference to some object, and for the sake of const-correctness you may also need to provide a const getter.

When you have a sufficiently stable object.

One trivial case is for a collection that returns the content that way. Kinda the primary job description.

For nonconst & another usual case is to return what you got in arguments (including the hidden this pointer). That could apply to const& in a similar way, but be aware of risks, when your param was bound to a temporary that will disappear in short time. Would work better if you got & and return const& after changing the content.

You can return reference to a data member, but it fits the "do not leak your guts" guideline.

In any case if you return ref, you must provide documentation to the client on the validity. If you start working out that description, you will discover whether it makes sense in the first place.

Another obvious case is identity objects, that can (or supposed) not to be copied. It make sense to have to accessors, one returning const& for mainstream use and another with write access.

For the very reason you specified: no copy is made .

If you're returning a large object, it is much more efficient to return a const reference than a copy of the object.

不制作副本更有效,特别是对于复杂类型或在其复制构造函数中执行大量工作的类型。

So you can avoid you function being misused as the one below does?

class A
{
int x;

public:

int show()
{
return x;
}

A(int a)
{
        x = a;
}

A const& operator+(A& inp)
{

inp.x = this->x + inp.x;

return inp;
}

};

int main()
{
A a(1),b(2),c(0),d(420);
a + b = d;
std::cout<<b.show();

}

This gives, 420 as output. The overload is supposed to be used as d = a + b , but there is nothing stopping the returned reference to be assigned a another object.

If you make the return type of the function as A const& The returned reference is constant and cant be assigned any other object. Hence the operator has to be used only as d = a + b and not allowing a + b = d etc.

g++ gives error error: passing 'const A' as 'this' argument of 'A& A::operator=(const A&)' discards qualifiers and effectively prevents such misuse.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM