1

I have in my project a couple of functions that create objects. For example, if you have a function that makes an object like this:

int& f()
{
    int *i = new int(5);
    return *i;
}

and then when you call that you do

int x = f();

or something like

std::cout << f();

what happens to the int that was created in the function? Is the reference handled like a normal variable or am I doing something terribly wrong? And if so, what is the correct way to make objects?

LogicStuff
  • 19,397
  • 6
  • 54
  • 74
user2271513
  • 121
  • 3

2 Answers2

7

This is terribly wrong, indeed. The moment you forget about your reference is the moment you'll leak a resource. And you're doing just that with int x = f();.

Same with the second case, std::cout << f(); - don't use this at all if you aren't going to delete that dynamically allocated int.

int is also passed to std::basic_ostream::operator<< by value, a copy is made. This doesn't actually matter, no normal code would accept a reference and then call delete &ref;.

Here's a link for you: RAII.


I can't know what you want from your contrived example, but consider returning by value, or using smart pointers in case of polymorphism.

Community
  • 1
  • 1
LogicStuff
  • 19,397
  • 6
  • 54
  • 74
  • So if I wanted to have a function that initialises an object then returns a reference to that object so you don't have to initialise two objects how would I go about that? – user2271513 Jul 31 '16 at 18:24
  • 1
    Do you mean to avoid a copy? [RVO](http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization) should be able to handle that. – LogicStuff Jul 31 '16 at 18:38
  • @user2271513 Shouldn't you use a constructor to initialize an object? – Bob__ Jul 31 '16 at 18:41
  • In this case the constructor is called in the function and then you do some other stuff to the object and then return it. So I have a class with a member function that returns an object of that class based on the members of the class – user2271513 Jul 31 '16 at 18:52
  • @user2271513 Returning such an object by value is perfectly valid common practice. RVO will kick in. Don't optimize prematurely. – LogicStuff Jul 31 '16 at 18:57
0

if you want to show that function delegates ownership of the created object with new you have to do it explicitly for example with std::unique_ptr. As you can see your function becomes self documented and you need not look into the body to understand who response for deleting:

std::unique_ptr<int> foo() {
   return std::make_unique<int>(5);
}
AnatolyS
  • 4,249
  • 18
  • 28