By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,824 Members | 1,255 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,824 IT Pros & Developers. It's quick & easy.

Catching return value in a const reference needed?

P: n/a
Hello, consider this complete program:
#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

class Hanna
{
public:
Hanna(const string& s)
:
s_(s)
{ cout << "normal ctor, name = " << s_ << endl; }

Hanna(const Hanna& inst)
:
s_(inst.s_)
{ cout << "copyctor, name = " << s_ << endl; }

~Hanna() { cout << "cleaning up " << s_ << endl; }

Hanna& operator=(const Hanna& rhs)
{
s_ = rhs.s_;

cout << "in operator=(), name = " << s_ << endl;

return *this;
}

private:
string s_;
};

static Hanna
func(const string& s)
{
Hanna anobj(s);

return anobj;
}

int
main()
{
cout << "Testing catching return value in normal object." << endl;

{
Hanna a = func("not catching const ref");

(void)a;
}

cout << "\nTesting catching return value in a const reference" <<
endl;

{
const Hanna& b = func("catching const ref");

(void)b;
}

return 0;
}
When run, the outut is:
$ ./runme
Testing catching return value in normal object.
normal ctor, name = not catching const ref
cleaning up not catching const ref

Testing catching return value in a const reference
normal ctor, name = catching const ref
cleaning up catching const ref

The program has been compiled with optimizations disabled (and
debugging turned on). I thought that I had to catch the return value in
a const reference (if possible), if I wanted to avoid ctor/dtor calls
but seems I dont have to...is this optimization part of the C++
specification?

/ E

Apr 8 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
static Hanna
func(const string& s)
{
Hanna anobj(s);

Here you create a local object of the type "Hanna".

return anobj;

Here you return a local object (by value) of the type "Hanna".

}

int
main()
{
cout << "Testing catching return value in normal object." << endl;

{
Hanna a = func("not catching const ref");

For clarity, maybe change that to:

Hanna a = func("Initialising local object with return value");

(void)a;
}

cout << "\nTesting catching return value in a const reference" <<
endl;

{
const Hanna& b = func("catching const ref");

Hanna b = func("Binding return value to a local const reference");

(void)b;
}

return 0;
}
When run, the outut is:
$ ./runme
Testing catching return value in normal object.
normal ctor, name = not catching const ref
cleaning up not catching const ref

Testing catching return value in a const reference
normal ctor, name = catching const ref
cleaning up catching const ref

The program has been compiled with optimizations disabled (and
debugging turned on). I thought that I had to catch the return value in
a const reference (if possible), if I wanted to avoid ctor/dtor calls
but seems I dont have to...is this optimization part of the C++
specification?

Yes, it's called something like "Eliding constructors"; it's an
optimization. The compiler though doesn't have to perform this optimization.
Without it, I would expect there to be three objects created rather than
one:

1) The local object in "func".

2) The object returned from "func".

3) The local object in "main".
If you only need a const object, I would advocate going the const reference
route.

If you need a non-const object, you could do what you have done, or you
could go for more elaborate means.

-Tomás
Apr 8 '06 #2

P: n/a
Eric Lilja wrote:
Hello, consider this complete program:
#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

class Hanna
{
public:
Hanna(const string& s)
:
s_(s)
{ cout << "normal ctor, name = " << s_ << endl; }

Hanna(const Hanna& inst)
:
s_(inst.s_)
{ cout << "copyctor, name = " << s_ << endl; }

~Hanna() { cout << "cleaning up " << s_ << endl; }

Hanna& operator=(const Hanna& rhs)
{
s_ = rhs.s_;

cout << "in operator=(), name = " << s_ << endl;

return *this;
}

private:
string s_;
};

static Hanna
Prefer placing functions like that in an unnamed namespace. Using
'static' with functions has been deprecated.
func(const string& s)
{
Hanna anobj(s);

return anobj;
}

int
main()
{
cout << "Testing catching return value in normal object." << endl;

{
Hanna a = func("not catching const ref");

(void)a;
}

cout << "\nTesting catching return value in a const reference" <<
endl;

{
const Hanna& b = func("catching const ref");

(void)b;
}

return 0;
}
When run, the outut is:
$ ./runme
Testing catching return value in normal object.
normal ctor, name = not catching const ref
cleaning up not catching const ref

Testing catching return value in a const reference
normal ctor, name = catching const ref
cleaning up catching const ref

The program has been compiled with optimizations disabled (and
debugging turned on). I thought that I had to catch the return value
in a const reference (if possible), if I wanted to avoid ctor/dtor
calls but seems I dont have to...is this optimization part of the C++
specification?


Yes. The compiler is allowed to optimise away creation of a temporary
when copy-constructing objects. The statement

Hanna a = func();

can end up optimised in such way that there is no temporary and the
function's return value is placed directly in the object being born.

V
--
Please remove capital As from my address when replying by mail
Apr 8 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.