returning a reference

S

Shea Martin

Trying to avoid a temp object, and c-style funcitons
(i.e., void doSomethingTo(Type* thisObject) ).

<referece: code below>

Is it safe to return a reference to an internally created object? Is
obj's destructor called at end of main or at end of fromString()?

This is how I uderstand it: o's copy constructor is called with obj as
the arg, and I have avoided a temporary instance of Object.

Is this safe?

Thanks

<code>
class Object
{
public:
static Object &fromString(std::string str)
{
Object obj;
//process string, and set attributes of obj
return obj;
}
};

int main()
{
Object o = Object::fromString("attribute1,attribute2");
cout << "att1 is " << o.getAtt1()
<< "att2 is " << o.getAtt1()
<< "att3 is " << o.getAtt1() << endl;
}
</code>
 
R

red floyd

Shea said:
Trying to avoid a temp object, and c-style funcitons
(i.e., void doSomethingTo(Type* thisObject) ).

<referece: code below>

Is it safe to return a reference to an internally created object? Is
obj's destructor called at end of main or at end of fromString()?
No. It's not safe. Destructor is called at the end of fromString().
This is how I uderstand it: o's copy constructor is called with obj as
the arg, and I have avoided a temporary instance of Object.

Is this safe?

Thanks

<code>
class Object
{
public:
static Object &fromString(std::string str)
Should be: static Object fromString(std::string str)
{
Object obj;
//process string, and set attributes of obj
return obj;
This is ungood. obj is destroyed at the end of fromString
Scott Meyers has a good discussion of this in Effective C++, where he points
out that while return by reference is nice for efficiency, there are cases
(such as this one) where you need to return by value.
}
};

int main()
{
Object o = Object::fromString("attribute1,attribute2");
cout << "att1 is " << o.getAtt1()
<< "att2 is " << o.getAtt1()
<< "att3 is " << o.getAtt1() << endl;
}
</code>


It's essentially the equivalent of the C construct:

int *f()
{
int x;
return &x;
}

When you return from f, the pointer is invalid. Similarly, when you return from fromString, the
reference doesn't refer to anything valid.

red floyd
 
J

jeffc

Shea Martin said:
Trying to avoid a temp object, and c-style funcitons
(i.e., void doSomethingTo(Type* thisObject) ).

<referece: code below>

Is it safe to return a reference to an internally created object?
Sometimes.

Is obj's destructor called at end of main or at end of fromString()?

Yes. This isn't one of those times :)
This is how I uderstand it: o's copy constructor is called with obj as
the arg, and I have avoided a temporary instance of Object.

There is no obj to use as an arg, since as you guessed it was destroyed
after leaving fromString.
 
R

Rolf Magnus

Shea said:
Trying to avoid a temp object, and c-style funcitons
(i.e., void doSomethingTo(Type* thisObject) ).
<referece: code below>

Is it safe to return a reference to an internally created object?
No.

Is obj's destructor called at end of main or at end of fromString()?

At the end of fromString().
This is how I uderstand it: o's copy constructor is called with obj
as the arg, and I have avoided a temporary instance of Object.
Wrong.

Is this safe?

Thanks

<code>
class Object
{
public:
static Object &fromString(std::string str)

You have to return an Object, not a reference. Btw, the above will copy
the std::string, so you should use a reference here:

static Object fromString(const std::string& str)

Btw, a good compiler optimzies the extra copy of function return values
away.
 
J

jeffc

Rolf Magnus said:
You have to return an Object, not a reference.

You can return a reference as long as the object is allocated dynamically.
This puts the responsibility for the object (deletion) with the caller.
 
J

Jonathan Mcdougall

Trying to avoid a temp object, and c-style funcitons
(i.e., void doSomethingTo(Type* thisObject) ).

Good idea, but sometimes you can't.
<referece: code below>

Is it safe to return a reference to an internally created object?
No.

Is
obj's destructor called at end of main or at end of fromString()?

Yes, when it gets out of scope, it is destroyed.
This is how I uderstand it: o's copy constructor is called with obj as
the arg, and I have avoided a temporary instance of Object.

It didn't have the time! 'obj' was destroyed before 'o' was ever aware
of its existence.
Is this safe?

No! 'Well it works on my computer'. That's bad since you'll have a lot of
troubles finding why it crashes 5 minutes (or an hour) after. This would
be called undefined behavior.
<code>
class Object
{
public:
static Object &fromString(std::string str)

Never, never return a reference to something if that something did not exist
prior entering a function (except for dynamically allocated memory, but then
I hope you'll go for pointers.
{
Object obj;

'obj' is created here.
//process string, and set attributes of obj
return obj;
}

'obj' is destroyed there.
};

int main()
{
Object o = Object::fromString("attribute1,attribute2");

fromString() returns a reference to an already destroyed object.
Undefined behavior. Don't do that!

When you want to return a object which was inexistant, do it
by value. You have got no other choices (except for dynamically
allocated memory, which is always something to avoid).


Jonathan
 
J

jeffc

Jonathan Mcdougall said:
Never, never return a reference to something if that something did not exist
prior entering a function (except for dynamically allocated memory, but then
I hope you'll go for pointers.

Why would you recommend pointers rather than references in that case?
 
J

Jonathan Mcdougall

public:
Why would you recommend pointers rather than references in that case?

Because it makes more sense :

int &f()
{
return *new int;
}

int *g()
{
return new int;
}


int main()
{
int &a = f();
int *b = g();

delete &a; // yurk
delete b;
}


Jonathan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top