0

I'm confused in how to deal with a function that intends to return a class object.

Here I have a function connect which accepts a url in the form of a char array and then creates an object of class Response which contains the response of visiting this url to return.

1> Return the response by value is the most straightforward, but people say copy constructor will make return by value kind of slow:

Response connect(char *); // declaration of connect  
Response resp = connect(url_str);  

2> Return the response by pointer is also easy to read, but need to handle deleting the pointer outside connect:

Response * connect(char *);  // declaration of connect  
Response * resp = connect(url_str);  

3> Declare an object of class Response before calling connect and pass it into connect via reference is good in reducing the risk of memory-leaks and also faster than return by value, but this makes the code counter-intuitive:

void connect(char *, Response &); // declaration of connect  
Response resp;  
connect(url_str, resp);  

How will you handle this kind of case in C++? Any suggestion or experience are welcome.

spoorcc
  • 2,907
  • 2
  • 21
  • 29
Lee
  • 535
  • 5
  • 19
  • 1
    One thing that may help is to mark input parameters as const and output parameters without const. This is a signal to anyone reading your API of which parameters can be modified. const has its own fun, of course, but that's one way to do it. – J Trana Feb 12 '14 at 05:05
  • I suggest using a smart pointer. If you can, unique_ptr is a more clear alternative than the general shared_ptr. Return-value optimization is not 100% guaranteed to happen if you use return-by-value, but if you use a smart pointer, you know you will not copy large objects by value. – Erik Alapää Mar 27 '15 at 10:19

4 Answers4

3

Return by value.

It's the simplest, the easiest to get right, and puts the least obligation on callers of your function.

In theory it's less efficient (you need both the original constructor and the copy constructor), but the C++ standard specifically allows what's called return value optimisation, so that the copy can be avoided. Every C++ compiler you're likely to use will perform this optimisation.

Tristan Brindle
  • 16,281
  • 4
  • 39
  • 82
  • I almost never return large objects by value - I use simpler mechanisms like smart pointers or passing in non-const references to be 100% sure that on any compiler, in any situation, no copy is made. – Erik Alapää Mar 27 '15 at 10:30
0

You might create a 'response' object which has a load(const char* url) method:

response somepage;
somepage.load( "http://www.google.com" );
Jay
  • 13,803
  • 4
  • 42
  • 69
  • This though not answers the question directly but gives me other ideas. Thanks. – Lee Feb 12 '14 at 19:17
0

The answer fully depends on the Response class structure and use cases. If the class has not a lot of data, is rarely used or you are not concerned about performance much - you can just return a class object. It's simple but not very effective.

Pure way 2 is dangerous because you have to care about memory. Better way in this case is to use smart pointers. Moreover, you can return a nullptr if the operation failed in this case.

The way 3 is the common practice. But you probably need a special method in Response to understand if it was successfully connected or not.

tkhomas
  • 103
  • 1
  • 8
  • Your comment about the way 3 is helpful. I see people prefer reference to pointer because it can't be NULL so don't have to test the NULL-ness, but in some cases the reference still need to be checked for validity. – Lee Feb 12 '14 at 19:20
0

A good reference on this issue can be found in Scott Meyers' Effective C++ 3rd edition, Item 21.

K.Chen
  • 1,166
  • 1
  • 11
  • 18
  • Item 21 is of completely different issue. It shows that the references or pointers to local objects should never be returned from a function. – tkhomas Feb 12 '14 at 06:04
  • Toward the end of Item 21, Meyer writes, "the right way to write a function that must return a new object is to have that function return a new object. " – K.Chen Feb 12 '14 at 06:26