AutoBotAM
AutoBotAM

Reputation: 1545

Returning a reference to an object constructor

Take a look at this code:

Foo &Bar::Copy()
{
    return Bar();
}

The class Bar is inherited from Foo, and Foo is an abstract class. But when I call Bar() and return it, is it safe to do so? Or would I be returning the address of a local variable that would be freed by the end of the Copy() function?

Advice is greatly appreciated!

Upvotes: 0

Views: 155

Answers (3)

ali_bahoo
ali_bahoo

Reputation: 4863

This is an undefined behaviour, because temporary Bar object will be destroyed at ;.

Foo Bar::Copy()
{
    return Bar();
}

is safer. BUT thanks to @Cat Plus Plus and @celtschk, I realized that this method leads to slicing, losing the all Bar specific information. In order to keep the Bar object Copy() must return either a reference or a pointer to the object. Here we are at the beginning again as this is UB. So Barmust be allocated dynamically instead, that its reference/pointer lives at the out of Copy() function. Who should be responsible for deleting this dynamically generated Bar object?

#include <memory>
std::shared_ptr<Foo> Bar::Copy()
{
    return std::shared_ptr(new Bar());
}

shared_ptr will do this automatically for you.

Upvotes: 0

Jerry Coffin
Jerry Coffin

Reputation: 490048

You're not returning a ctor. Bar(); invokes the ctor, creating a temporary object. You're then returning a reference to that temporary object.

Since a ctor in C++ doesn't have a name, you can't do many of the usual things you could on normal functions, such as getting/returning a pointer to a function. It's no entirely clear what you're really trying to accomplish here, but if you want to return something that will construct an object, you usually need to define a static member function that invokes the ctor, and return a pointer to that static member function.

Upvotes: 1

jszpilewski
jszpilewski

Reputation: 1632

When calling Bar(); you call constructor on an implicit temporary object to which reference is returned. If you intend to create a Clone() like function a typical solution is to create the clone on the heap with new. You may use a kind of smart pointer to simplify life cycle management. You may also apply covariant return type to avoid type conversions in some cases using signature: Bar &Bar::Copy()

Upvotes: 1

Related Questions