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

const reference to object returned by value

P: n/a
Hi,

I'm looking at the differences between:

const NonTrivialObject& obj =
functionThatReturnsANonTrivialObjectByValue();

and:

const NonTrivialObject obj =
functionThatReturnsANonTrivialObjectByValue();

My question is, can I expect these two lines to be any different?

I assumed that the object returned by the function becomes a
temporary. In the first line, I thought that the const reference
would be bound to that temporary, causing the temporary to hang around
until the reference dies.

In the second line, I assumed that the temporary returned from the
function is then copied into 'obj'. Hence, the first line saves a
copy. My testing has proven this completely wrong. See the following
code and results. Is there anything in the standard that could
clarify this, or is this completely compiler-specific?

The code below compiled in gcc 3.4.4 outputs:
Start.
Copy!
A
B
C
Copy!
D
E
F

Microsoft CL 14.00.5 (from VS 8.0) outputs:
Start.
Copy!
A
B
Copy!
C
Copy!
D
E
Copy!
F

Code:

#include <iostream>
class testClass {
public:
testClass() { }

testClass(const testClass& t) { std::cerr << "Copy!\n"; }
};

class ObjectFactory {
public:
ObjectFactory() { }
testClass getResidentObject() const {
return m_object;
}

testClass getLocalTempObject() {
return testClass();
}

testClass getLocalObject() {
testClass t;
return t;
}

private:
testClass m_object;
};

int main() {
ObjectFactory of;
std::cerr << "Start.\n";

const testClass& t1 = of.getResidentObject();
std::cerr << "A\n";

const testClass& t2 = of.getLocalTempObject();
std::cerr << "B\n";

const testClass& t3 = of.getLocalObject();
std::cerr << "C\n";

const testClass t4 = of.getResidentObject();
std::cerr << "D\n";

const testClass t5 = of.getLocalTempObject();
std::cerr << "E\n";

const testClass t6 = of.getLocalObject();
std::cerr << "F\n";

return 0;
}

Any insight would be appreciated. Basically, I'm trying to decide if
it's ever worth using a const reference to refer to something returned
from a function.

Ryan

Aug 29 '07 #1
Share this Question
Share on Google+
3 Replies


P: n/a
On Aug 29, 1:57 pm, rwf_20 <rfr...@gmail.comwrote:
Hi,

I'm looking at the differences between:

const NonTrivialObject& obj =
functionThatReturnsANonTrivialObjectByValue();

and:

const NonTrivialObject obj =
functionThatReturnsANonTrivialObjectByValue();

My question is, can I expect these two lines to be any different?

I assumed that the object returned by the function becomes a
temporary. In the first line, I thought that the const reference
would be bound to that temporary, causing the temporary to hang around
until the reference dies.

In the second line, I assumed that the temporary returned from the
function is then copied into 'obj'. Hence, the first line saves a
copy. My testing has proven this completely wrong. See the following
code and results. Is there anything in the standard that could
clarify this, or is this completely compiler-specific?

The code below compiled in gcc 3.4.4 outputs:
Start.
Copy!
A
B
C
Copy!
D
E
F

Microsoft CL 14.00.5 (from VS 8.0) outputs:
Start.
Copy!
A
B
Copy!
C
Copy!
D
E
Copy!
F

Code:

#include <iostream>
class testClass {
public:
testClass() { }

testClass(const testClass& t) { std::cerr << "Copy!\n"; }

};

class ObjectFactory {
public:
ObjectFactory() { }
testClass getResidentObject() const {
return m_object;
}

testClass getLocalTempObject() {
return testClass();
}

testClass getLocalObject() {
testClass t;
return t;
}

private:
testClass m_object;

};

int main() {
ObjectFactory of;
std::cerr << "Start.\n";

const testClass& t1 = of.getResidentObject();
std::cerr << "A\n";

const testClass& t2 = of.getLocalTempObject();
std::cerr << "B\n";

const testClass& t3 = of.getLocalObject();
std::cerr << "C\n";

const testClass t4 = of.getResidentObject();
std::cerr << "D\n";

const testClass t5 = of.getLocalTempObject();
std::cerr << "E\n";

const testClass t6 = of.getLocalObject();
std::cerr << "F\n";

return 0;

}

Any insight would be appreciated. Basically, I'm trying to decide if
it's ever worth using a const reference to refer to something returned
from a function.

Ryan
Look at your type definitions. "const Type& myObj" is a constant
reference and "const Type myObj" is a constant object. In either case
you are not allowed to change the value after initialization. Any
attempt to change their contents should throw a compiler warning/
error. And yes, you can expect these lines to be very different from
one another. Read some articles on C++ references and constant
modifiers.

Aug 29 '07 #2

P: n/a
On Aug 29, 2:06 pm, spekyuman <spekyu...@gmail.comwrote:
Look at your type definitions. "const Type& myObj" is a constant
reference and "const Type myObj" is a constant object. In either case
you are not allowed to change the value after initialization. Any
attempt to change their contents should throw a compiler warning/
error.
I'm aware of that. I don't think my question really has anything to
do with const.
And yes, you can expect these lines to be very different from
one another.
Really? Because the output of my tests implies that they are the same
with respect to creation of temporaries and calls to the copy
constructor. I understand that the result of each statement is
different (a reference vs. an object). But, other than that, each
results in a variable that can be used the same way and have the same
lifetime. How did you mean they would be 'very different'?
Aug 29 '07 #3

P: n/a
There are a couple of effects that are coming into play with your code.

1) RVO and NRVO can often remove copies. (You will get much the same
output as gcc with MSVC if you turn on full optimizations as MSVC doesn't
apply NRVO optimisations normally).

2) However, that isn't what's causing the confusion. What is causing the
confusion is that code like:

const testClass t4 = of.getResidentObject();

isn't actually doing an assignment. It is instead invoking the constructor
for t4 with of.getResidentObject() as it's argument. That immediately
removes one of your expected copies.

Try using non-const declarations and then declaring it like:

testClass t4;
t4 = of.getResidentObject();

I would expect to see a difference then.

joe
Aug 29 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.