Click here to Skip to main content
15,892,059 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi all,

I wish to return an object from a method in c++,

If I allocate the object on the stack in the following way:

C++
class A
{

  B GetObject()
  {
    B b(5);

    return b;
  }

};

public void main()
{
  A a;
  B b = a.GetObject();
}


Will the copy constructor of b (in the main) will always be called before the destructor of the B object defined on the stack?

Is this the preferable way to pass objects from methods in C++?

I don't want to allocate the object on the heap since it won't be clear who is responsible for deleting it.

Thanks in advance,
Anton
Posted
Updated 21-Aug-14 7:52am
v2

The method you have shown is viable if class B is relatively small. Returning the object by value means that the object will have to be copied to a temporary object on the stack (via its copy constructor), then it will have to be copied to the b object in the calling program (again via its copy constructor), and finally the temporary object on the stack will be destroyed. Admittedly, modern compilers can optimize much of this overhead away. But what remains is at least one call to the copy constructor.

The alternative is to create the object on the heap and return a pointer. As you have pointed out correctly, this leaves the responsibility of deleting the object with the caller, which is somewhat unpleasant, even if you emphasize this in the documentation of your function. It has also another disadvantage: Allocating space from the heap is generally more time consuming than allocating from the stack. For bigger objects this is however the way to go, and the heap overhead is comparatively small.

The disadvantage of putting the responsibility for the deletion of the object on the caller's shoulder can be avoided by returning an auto-pointer to the object. That way the caller cannot forget to delete it.

The third method would be to allocate the object on the stack by the caller and transfer a reference to it. Your function is then responsible for initializing the object, but ownership remains with the caller. This is generally the fasted method, but cannot always be used, because some classes require already some arguments in their constructor, which you now have to satisfy in the calling function -- not what you actually wanted. To use this method the class must be designed to be initialized in that way.

So, there is no perfect method that fits all. In languages like C# everything looks so much easier. But then again, in C# you would always create the object on the heap (except for value-type objects) and hence incur always the performance penalty of using the heap.
 
Share this answer
 
your code is problematic. Because it is going out of scope ou return an destroyed object.

I prefer two solution
C++
B* GetObject()
{
 B *b = new B(5);

return b; 
}
//My preferred way is "pass per reference" the object but do work

bool FillObject(B& b)
{
 b.value = 5;

 return true;//real error checking
}

//call
FillObject(theObject);


why dont your write only
B *b = new B(5);

???
 
Share this answer
 
Comments
Anton Kaminsky 21-Aug-14 14:13pm    
Like I've wrote if I call "new B" in class A, I leave the responsibility of deleting the object to the user in the main and I don't want that.
I have added a print in the copy constructor and the destructor and it seems that the copy constructor does get executed before the destructor, but I wonder if I can count on that.
Sergey Alexandrovich Kryukov 21-Aug-14 16:19pm    
You would be right it it was something like malloc. C++ provides uniform way of allocating and deallocating. If you need to pass some object in different system, say, non-OOP, you could accompany GetObject with DestroyObject. In C++ context, this is not a problem. Moreover, the whole idea to provide a factory for the class B without late binding makes no sense at all (and my have deep sense with late binding and set of different types, then the factory would return an object of the type with the abstract compile-time type). Last line above illustrates this.

In C++ technology, an object allocated on stack is deallocated automatically at the moment of leaving the stack frame where it was allocated, period.

—SA
Sergey Alexandrovich Kryukov 21-Aug-14 16:14pm    
Some good points here; I up-voted. Only 4, due to one really bad suggestion: using Boolean for error checking, and returning anything like error status in general. After exceptions were invented, it became a poor evil.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900