Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > What to return -- object, reference or const reference

Reply
Thread Tools

What to return -- object, reference or const reference

 
 
Arv
Guest
Posts: n/a
 
      03-06-2008
After writing code in Java for sometime, one thing that I am not
comfortable at all with C++ is the return type of an object.

In java, i do not remember ever seeing a method return a final
reference -- though a const is not equivalent to final, it is
confusing when i see some methods returning a const reference.

I initially assumed returning an object is same as returning a
reference, because when i call the method as

Myclass O1;

O1 = func();

Does it matter if func() returns a reference, const reference or a
Object, anyways the assignment operator is going to get called.

But I am a bit confused when I call AnotherFunc(func())... so is it
possible that if I dont pass a const reference, and the AnotherFunc
accepts a reference, it can potentially change the object I pass.!

Especially this is more confusing in a getter method, should a getter
return a const reference always, because I do not want ppl to modify
the reference they get by calling a getter.

Sorry if this is a bit basic, but I have not been able to understand
this very clearly...

Thanks
Arv
 
Reply With Quote
 
 
 
 
Tom
Guest
Posts: n/a
 
      03-06-2008
On 6 Mrz., 10:10, Arv <(E-Mail Removed)> wrote:
> Does it matter if func() returns a reference, const reference or a
> Object, anyways the assignment operator is going to get called.

For the assignment: I don't think so, unless you overload the assigned
operation. In that case, anything is possible.

But returning a reference allows modification of the returned object,
like:
func().MyModifyFunction();

That's why overloaded [] operator usually return a reference and not a
copy of the object.

Thomas
-------------------------
Synchronize your Outlook:
http://www.easy2sync.com/en/produkte/e2s4o.php
 
Reply With Quote
 
 
 
 
EventHelix.com
Guest
Posts: n/a
 
      03-06-2008
On Mar 6, 4:10*am, Arv <(E-Mail Removed)> wrote:
> After writing code in Java for sometime, one thing that I am not
> comfortable at all with C++ is the return type of an object.
>
> In java, i do not remember ever seeing a method return a final
> reference -- though a const is not equivalent to final, it is
> confusing when i see some methods returning a const reference.
>
> I initially assumed returning an object is same as returning a
> reference, because when i call the method as
>
> Myclass O1;
>
> O1 = func();
>
> Does it matter if func() returns a reference, const reference or a
> Object, anyways the assignment operator is going to get called.
>
> But I am a bit confused when I call AnotherFunc(func())... so is it
> possible that if I dont pass a const reference, and the AnotherFunc
> accepts a reference, it can potentially change the object I pass.!
>
> Especially this is more confusing in a getter method, should a getter
> return a const reference always, because I do not want ppl to modify
> the reference they get by calling a getter.
>
> Sorry if this is a bit basic, but I have not been able to understand
> this very clearly...
>
> Thanks
> Arv


In C++ returning an object is suitable only when the object contains
only a few data members. Returning an object results in a copy of
entire object thus it can have really impact performance if objects
with a large list of data members is returned.

Note that in an object return, the copy constructor gets called (if
defined). If the copy constructor is not defined, an exact copy of the
object is returned.

An object copy can result in hard to debug memory allocation issues.
Consider the case where the object being copied contained pointers to
dynamically allocated memory. Only the pointers would be copied. Thus
both objects would be pointing to the same allocated memory.

--
EventStudio 4.0 - http://www.Eventhelix.com/Eventstudio/
Sequence diagram based systems engineering tool
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      03-06-2008
On Mar 6, 10:10 am, Arv <(E-Mail Removed)> wrote:
> After writing code in Java for sometime, one thing that I am not
> comfortable at all with C++ is the return type of an object.


> In java, i do not remember ever seeing a method return a final
> reference -- though a const is not equivalent to final, it is
> confusing when i see some methods returning a const reference.


C++ isn't Java, and you can't always make direct comparisons.
In this case, C++ has full support for value semantics, and so
allows considerably safer idioms.

Generally speaking, returning a value should be the default
action. You only return a reference when you explicitly want to
support access to internal data. In particular: you never, ever
return a reference (const or not) to a local variable or a
temporary (the results of an expression).

Typically, when you return a reference, it's because you're
allowing access to internal data: the operator[] of container
classes would be an obvious example, but one can imagine others.

Because of this, it's very, very rare to return a const
reference (although there, too, there are exceptions).
Basically, the goal behind the const reference is that the
client code can save it, and although it cannot modify the data,
it will see any modifications from other sources through the
saved reference.

> I initially assumed returning an object is same as returning a
> reference, because when i call the method as


> Myclass O1;


> O1 = func();


> Does it matter if func() returns a reference, const reference
> or a Object, anyways the assignment operator is going to get
> called.


In this case, it probably doesn't matter. Unless, of course,
the returned value is a local variable or a temporary, in which
case, returning the reference means that the code won't work.

> But I am a bit confused when I call AnotherFunc(func())... so
> is it possible that if I dont pass a const reference, and the
> AnotherFunc accepts a reference, it can potentially change the
> object I pass.!


If you're returning a non-const reference, this is the behavior
you're targetting.

> Especially this is more confusing in a getter method, should a
> getter return a const reference always, because I do not want
> ppl to modify the reference they get by calling a getter.


Well, mostly, you should not have that many "getter"
functions. However... typically, a getter should return a
value. Unless, of course, what you are getting is something you
want to share.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      03-06-2008
On Mar 6, 12:16 pm, "EventHelix.com" <(E-Mail Removed)> wrote:
> On Mar 6, 4:10 am, Arv <(E-Mail Removed)> wrote:
> > After writing code in Java for sometime, one thing that I am not
> > comfortable at all with C++ is the return type of an object.


> > In java, i do not remember ever seeing a method return a final
> > reference -- though a const is not equivalent to final, it is
> > confusing when i see some methods returning a const reference.


> > I initially assumed returning an object is same as returning a
> > reference, because when i call the method as


> > Myclass O1;


> > O1 = func();


> > Does it matter if func() returns a reference, const reference or a
> > Object, anyways the assignment operator is going to get called.


> > But I am a bit confused when I call AnotherFunc(func())... so is it
> > possible that if I dont pass a const reference, and the AnotherFunc
> > accepts a reference, it can potentially change the object I pass.!


> > Especially this is more confusing in a getter method, should a getter
> > return a const reference always, because I do not want ppl to modify
> > the reference they get by calling a getter.


> In C++ returning an object is suitable only when the object
> contains only a few data members. Returning an object results
> in a copy of entire object thus it can have really impact
> performance if objects with a large list of data members is
> returned.


That's bullshit. Return by reference results in different
semantics than return by value, and you can't simply replace one
with the other. The default return type in C++ is by value
(just as the default behavior everywhere is by value). If you
have a performance problem, and the profiler shows it to be due
to excess copies, then most of the time, the solution is to use
an out parameter, rather than return by reference.

> Note that in an object return, the copy constructor gets
> called (if defined). If the copy constructor is not defined,
> an exact copy of the object is returned.


If no accessible copy constructor is defined, you can't copy,
period. If no user-defined copy constructor is declared, the
copy is member by member, not "exact" (whatever that means---I
would assume bitwise).

> An object copy can result in hard to debug memory allocation
> issues. Consider the case where the object being copied
> contained pointers to dynamically allocated memory. Only the
> pointers would be copied. Thus both objects would be pointing
> to the same allocated memory.


Not providing a copy constructor when one is needed will cause a
number of problems. Regardless of whether you return by value
or return by reference. One of the very first things one learns
in C++ is to either ensure that the copy constructor works
correctly, or that copy is inhibited.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      03-06-2008
On Mar 6, 4:10 am, Arv <(E-Mail Removed)> wrote:
> After writing code in Java for sometime, one thing that I am not
> comfortable at all with C++ is the return type of an object.
>
> In java, i do not remember ever seeing a method return a final
> reference -- though a const is not equivalent to final, it is
> confusing when i see some methods returning a const reference.
>
> I initially assumed returning an object is same as returning a
> reference, because when i call the method as
>
> Myclass O1;
>
> O1 = func();
>
> Does it matter if func() returns a reference, const reference or a
> Object, anyways the assignment operator is going to get called.
>
> But I am a bit confused when I call AnotherFunc(func())... so is it
> possible that if I dont pass a const reference, and the AnotherFunc
> accepts a reference, it can potentially change the object I pass.!
>
> Especially this is more confusing in a getter method, should a getter
> return a const reference always, because I do not want ppl to modify
> the reference they get by calling a getter.
>
> Sorry if this is a bit basic, but I have not been able to understand
> this very clearly...


The below rules cover most situations for both parameters and return
values.

Returning by const reference is an optimization over returning by
value that you can use when you know that the object returned will
outlive the function returning it, the caller will not likely be
making a copy of its own, but be sure to let the caller know (through
documentation) how long that reference will be good for.

Returning by non-const reference is only for special situations where
the object being returned is either something that the caller has
access to anyway (for example returning a reference parameter that was
passed in, or a global,) or something that the function is
specifically designed to allow access to (for example containers, and
lazy initializers.)

Function parameters should be passed in by non-const reference only
when the function is specifically designed to modify the object passed
in (for example if the parameter is being used as output, or input and
output.) Otherwise the parameter should be by value if its size is
known to be equal to or less than sizeof(int) and the object
constructor (if it has one) is known not to allocate memory.
Otherwise, the parameter should be a const reference.

You may notice that I didn't mention pointers in the above, they
generally follow the same rules as references when you are talking
about the object the pointer points to, they follow the same rules as
objects when you are talking about the pointer object *itself*.

In summary:

T func(); // default
const T& func(); // only when you know that the value returned will
outlive func
// and its use by the caller
T& func(); // only if the caller has access to the object anyway, or
you specifically
// want to grant access to it

void func( const T& t ); // default
void func( T t ); // if the memory required by the object is known to
be small
void func( T& t ); // if 't' is being used as an output parameter
 
Reply With Quote
 
Richard Herring
Guest
Posts: n/a
 
      03-06-2008
In message
<(E-Mail Removed)>,
EventHelix.com <(E-Mail Removed)> writes

[...]
>
>In C++ returning an object is suitable only when the object contains
>only a few data members. Returning an object results in a copy of
>entire object thus it can have really impact performance if objects
>with a large list of data members is returned.


You're recommending premature optimisation, which is never a good idea.
If _measurement_ indicates that this copy has an impact on performance,
_then_ consider an alternative.
>
>Note that in an object return, the copy constructor gets called (if
>defined). If the copy constructor is not defined, an exact copy of the
>object is returned.


Not "exact", memberwise, which does whatever the members' copy
constructors say it does.
>
>An object copy can result in hard to debug memory allocation issues.
>Consider the case where the object being copied contained pointers to
>dynamically allocated memory.


Then you should have either defined an appropriate copy constructor (and
probably a copy assigment operator and destructor), or disabled copying.
Don't blame the user if you provide him with a fundamentally broken
class.

>Only the pointers would be copied. Thus
>both objects would be pointing to the same allocated memory.


Return by reference can result in hard to debug pointer issues.
Consider the case where instead of a copy, you return a dangling
reference to a local variable which has gone out of scope and been
deleted. Thus the non-reference refers to a non-object which is
not-pointing to some not-allocated memory. If you'd only returned a
properly-constructed copy, none of this would have happened.

--
Richard Herring
 
Reply With Quote
 
Yannick Tremblay
Guest
Posts: n/a
 
      03-06-2008
In article <(E-Mail Removed)>,
EventHelix.com <(E-Mail Removed)> wrote:
>
>In C++ returning an object is suitable only when the object contains
>only a few data members. Returning an object results in a copy of
>entire object thus it can have really impact performance if objects
>with a large list of data members is returned.


This is incorrect, what you are suggesting is:
a) premature optimisation
b) optimisable by your compiler (google NRVO)
c) in most situation false (measure it!)

With optimisation turned on,

std::vector<someType> computeLargeVector();
std::vector<someType> v = computeLargeVector();

is going to be as fast if not faster as:

void computeLargeVector(std::vector<someType> &v);
std::vector<someType> v;
computeLargeVector(v);

(1st might be faster because the default constructor for vector will never
be called). Test and measure!

>Note that in an object return, the copy constructor gets called (if
>defined). If the copy constructor is not defined, an exact copy of the
>object is returned.


Any object for which the default compiler-generated copy constructor
is not suitable should either be made:
a) explicitely non-copyable
b) have a valid copy-constructor supply (and assigment...)

>An object copy can result in hard to debug memory allocation issues.
>Consider the case where the object being copied contained pointers to
>dynamically allocated memory. Only the pointers would be copied. Thus
>both objects would be pointing to the same allocated memory.


That is correct if you have an invalid copy constructor but that's a
bug in your class, you should fix the class rather than promote
obfuscating practices.

Yan



 
Reply With Quote
 
Micah Cowan
Guest
Posts: n/a
 
      03-06-2008
Richard Herring <junk@[127.0.0.1]> writes:

> In message
> <(E-Mail Removed)>,
> EventHelix.com <(E-Mail Removed)> writes
>
> [...]
>>
>>In C++ returning an object is suitable only when the object contains
>>only a few data members. Returning an object results in a copy of
>>entire object thus it can have really impact performance if objects
>>with a large list of data members is returned.

>
> You're recommending premature optimisation, which is never a good
> idea. If _measurement_ indicates that this copy has an impact on
> performance, _then_ consider an alternative.


Preemptive optimization is not the same thing as premature
optimization (not all of the former are the latter). The latter
usually involves small-gain optimizations. Choosing good algorithms,
and making obviously smart decisions, are examples of the former that
are not in the latter set.

Are you seriously claiming that you never use a reference as return
type for performance reasons only, unless you've first tried it by
value and verified what you already knew to be true: that it's
significantly more efficient to return the reference (for objects
other than those that contain "only a few data members")?

--
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/
 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      03-06-2008
On Mar 6, 1:24*pm, Micah Cowan <(E-Mail Removed)> wrote:
>
> Are you seriously claiming that you never use a reference as return
> type for performance reasons only, unless you've first tried it by
> value and verified what you already knew to be true: that it's
> significantly more efficient to return the reference (for objects
> other than those that contain "only a few data members")?


What is seriously being claimed is that your comment above, (that it's
significantly more efficient to return the reference) is not generally
true.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
is const necessary in eg int compar(const void *, const void *) lovecreatesbeauty@gmail.c0m C Programming 26 11-10-2008 09:47 PM
non-const reference and const reference George2 C++ 10 12-17-2007 02:19 PM
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Casting int'** to 'const int * const * const' dosn't work, why? Jonas.Holmsten@gmail.com C Programming 11 07-01-2007 06:16 PM
const class reference return from function, what does const do? Jim Langston C++ 2 05-11-2006 09:49 AM



Advertisments