-
September 19th, 2005, 09:04 AM
#1
const reference
Hi,
I was wondering what is the meaning of a function returning a const reference?
for example I have a function that defined like this:
const int& getNum() const;
how do I call this function, is
int i = getNum();
ok?
Thanks
Avi123
-
September 19th, 2005, 09:15 AM
#2
Re: const reference
Originally Posted by avi123
Hi,
I was wondering what is the meaning of a function returning a const reference?
for example I have a function that defined like this:
const int& getNum() const;
how do I call this function, is
int i = getNum();
ok?
Thanks
Avi123
the answer is yes,
-
Code:
int num = getNum(); // ok.
// num can be modified here
num = 123; // ok
-
Code:
int &num1= getNum(); // not ok
-
Code:
const int &num2= getNum(); // ok
// but here num2 cannot be modified!!!
num2 = 123; // not ok
Cheers
-
September 19th, 2005, 09:26 AM
#3
Re: const reference
Normally you would not return an int by const reference unless done through a template (thus you are handling all types).
However there is an advantage of returning a full object by const reference because then it does not need to copy the object. (And the object might not be copyable anyway).
-
September 19th, 2005, 10:52 AM
#4
Re: const reference
Originally Posted by golanshahar
the answer is yes,
-
Code:
int num = getNum(); // ok.
// num can be modified here
num = 123; // ok
-
Code:
int &num1= getNum(); // not ok
-
Code:
const int &num2= getNum(); // ok
// but here num2 cannot be modified!!!
num2 = 123; // not ok
Cheers
about the first answer, I don't understand if I use int num = getNum() , does it mean that I canceled the const?
another thing abuot the first answer, what if I get out of the scope of the int num that got return value of GetNum, does it mean that the value getNum has returned is now corrupted? (since it returned a reference)?
Thanks again
Avi123
-
September 19th, 2005, 10:53 AM
#5
Re: const reference
Originally Posted by NMTop40
Normally you would not return an int by const reference unless done through a template (thus you are handling all types).
However there is an advantage of returning a full object by const reference because then it does not need to copy the object. (And the object might not be copyable anyway).
Hi,
I'm not really returning an int but a reference to a struct I defined, it was just a simple example
The thing is that I don't really understand the meaing of a const reference return value, can you pls explain it to me?
Thanks again
Avi123
-
September 19th, 2005, 11:07 AM
#6
Re: const reference
Originally Posted by avi123
Hi,
I'm not really returning an int but a reference to a struct I defined, it was just a simple example
The thing is that I don't really understand the meaing of a const reference return value, can you pls explain it to me?
Thanks again
Avi123
A const reference is basically just implemented as a pointer to the structure.
But a const reference is used like a value (because it is a reference).
Morevoer, since it is const, the user cannot (except if he uses a const_cast) modify the structure via this reference.
Finally returning const references is faster then returning values, and is equivalent with a restriction:
The lifetime of the const reference returned is the lifetime of the object returned, so, for example, you must not return a local variable by const-reference, but, in a method, you can return a const-reference to a member variable of the class (or any data which has the lifetime of the object, such as std::vector:perator[]const does).
Of course, the class's user must know that this const-reference has only the lifetime of the class's object, and may copy the value if he wants to save this value after the object destruction.
"inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
Club of lovers of the C++ typecasts cute syntax: Only recorded member.
Out of memory happens! Handle it properly!
Say no to g_new()!
-
September 19th, 2005, 11:17 AM
#7
Re: const reference
A reference is very similar to a pointer - it refers to another object rather than 'being' that object.
When you return a const reference, you're saving the time and effort for the compiler to copy the object - consider this:
Code:
struct Foo
{
int a[10000];
};
Foo Function1()
{
Foo bar;
// fill in bar here
return bar;
}
const Foo& Function2()
{
static Foo bar; // See note below!
// prepares bar here (again, see note)
return bar;
}
In Function1, the compiler creates a 'Foo' on the stack (all ~40k of it!), then your code fills it in. When you return it by value, the compiler must copy it to the caller! Unlike say a float, or an int (which generally fits into a processor register) this takes some time. (there's also all sorts of extra things that could happen in the copy constructor or operator=() for the class, but I won't go into that here). In most cases, you'll want to avoid code like Function1().
In Function2, a reference to an existing Foo object is returned. This is just like a pointer, so is quick. Of course, you wouldn't necessarily want callers to Foo to be able to modify the object you're making a reference to, hence the const reference.
Note that in this trivial example I've had to use a static Foo object - this is generally bad practice - but reinforces an important thing you have to think about when returning references (and indeed pointers) - the lifetime of the object you return a reference to must equal or exceed that of the reference(/pointer) you return! This is made easier when you're using objects: an object's member function could return a const reference to one of its member variables as a way of implementing an accessor:-
Code:
class Foo
{
private:
Baz mBazObject; // a 'large' object representing some internal state
public:
// Accessors and mutators:
const Baz& GetBaz() const { return mBazObject; }
void SetBaz(const Baz& iBaz) { mBazObject = iBaz; }
};
Edit: one important thing to note is in order to reap the benefits of using references you'll have to declare your variables as references too:
Code:
const Baz& bazObjectRef = foo.GetBaz(); // Good
Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object
For more practical purposes the const reference is utterly equivalent to the object itself - unless you want to change it.
Using const references is a Good Thing - but it will also expose lots of issues in your code if you haven't been const correct throughout - something I really recommend you do both from an optimisation point of view, and a sheer design-by-contract idea.
Last edited by TheMoog; September 19th, 2005 at 11:22 AM.
Reason: Missed out an important point!
-
September 20th, 2005, 02:27 AM
#8
Re: const reference
Originally Posted by TheMoog
Edit: one important thing to note is in order to reap the benefits of using references you'll have to declare your variables as references too:
Code:
const Baz& bazObjectRef = foo.GetBaz(); // Good
Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object
For more practical purposes the const reference is utterly equivalent to the object itself - unless you want to change it.
Using const references is a Good Thing - but it will also expose lots of issues in your code if you haven't been const correct throughout - something I really recommend you do both from an optimisation point of view, and a sheer design-by-contract idea.
what if I use this:
Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object
I understand it really copies the object, but does it have any pthere problems? for example what if I change the local bazObject does it effect the member somehow? and when I get out of scope of the local bazObject?
Thanks
avi123
-
September 20th, 2005, 02:31 AM
#9
Re: const reference
Originally Posted by avi123
what if I use this:
Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object
I understand it really copies the object, but does it have any pthere problems? for example what if I change the local bazObject does it effect the member somehow? and when I get out of scope of the local bazObject?
There will be no problems at all using this - you've taken a copy of the object, and so modifying 'bazObject' will NOT alter the original. Similarly when bazObject goes out of scope, the original will also not be affected.
For completeness: This is only true if the 'Baz' object itself has proper copy semantics -- if Baz holds a pointer to another object (say, Bob) which isn't 'deep copied', then when you take a copy of the Baz object you're still only taking a copy of a reference to the Bob -- modifying Baz might then alter the original Bob referred to by Baz. All rather complex sounding, I can probably rustle up an example if that's confusing!
-
September 21st, 2005, 08:46 AM
#10
Re: const reference
Originally Posted by TheMoog
There will be no problems at all using this - you've taken a copy of the object, and so modifying 'bazObject' will NOT alter the original. Similarly when bazObject goes out of scope, the original will also not be affected.
For completeness: This is only true if the 'Baz' object itself has proper copy semantics -- if Baz holds a pointer to another object (say, Bob) which isn't 'deep copied', then when you take a copy of the Baz object you're still only taking a copy of a reference to the Bob -- modifying Baz might then alter the original Bob referred to by Baz. All rather complex sounding, I can probably rustle up an example if that's confusing!
and if I have a copy constructor will it be called when I use:
Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object
Thanks again
avi123
-
September 21st, 2005, 10:28 AM
#11
Re: const reference
Originally Posted by avi123
and if I have a copy constructor will it be called when I use:
Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object
Thanks again
avi123
Yes.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
September 22nd, 2005, 01:50 AM
#12
Re: const reference
Originally Posted by Graham
Yes.
Then what is the probelm using it?
I mean besdie efficency...
Thanks
avi123
-
September 22nd, 2005, 02:08 AM
#13
Re: const reference
It is just less efficient (for objects having a heavy copy construction) than const Baz &bazObject = foo.GetBaz();, but has no more problem.
Moreover Baz bazObject = foo.GetBaz(); has an efficiency very near than return by value, but is a bit less efficient when dealing with very small objects such as int.
Finally, you should return an object by const-reference instead of returning it by value if:
- The lifetime of the object is sufficient (for example if the referenced object at the same lifetime than the object whose method is called).
- And the object is not too small (for example 4 bytes values are fastly returned by value).
This slowing factor is not very important.
If the type is templatized, you cannot know if it is small or big, so in the doubt you should assume that it is big, and return by const-reference.
"inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
Club of lovers of the C++ typecasts cute syntax: Only recorded member.
Out of memory happens! Handle it properly!
Say no to g_new()!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|