Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning an object or a pointer in C++

In C++, should my method return an object or a pointer to an object? How to decide? What if it's an operator? How can I define?

And one more thing - if the pointer turns to be a vector, how can I find out its size after returned? And if it's impossible, as I think it is, how should I proceed to correctly return an array without this limitation?

like image 505
Luan Nico Avatar asked Nov 03 '12 22:11

Luan Nico


People also ask

Can you return a pointer in C?

Pointers in C programming language is a variable which is used to store the memory address of another variable. We can pass pointers to the function as well as return pointer from a function.

What is the return type of a pointer?

Return Function Pointer From Function: To return a function pointer from a function, the return type of function should be a pointer to another function. But the compiler doesn't accept such a return type for a function, so we need to define a type that represents that particular function pointer.

What is a returning object?

When an object is returned by value from a function, a temporary object is created within the function, which holds the return value. This value is further assigned to another object in the calling function. The syntax for defining a function that returns an object by value is. 1.

Why we should not return a pointer to a local variable?

The return statement should not return a pointer that has the address of a local variable ( sum ) because, as soon as the function exits, all local variables are destroyed and your pointer will be pointing to someplace in the memory that you no longer own.


2 Answers

In C++, should my method return an object or a pointer to an object? How to decide?

Since C++11 we have move semantics in C++ which means that it as easy as before and now also fast to return by value. That should be the default.

What if it's an operator? How can I define?

Many operators such as operator= normally return a reference to *this

X& X::operator=(X rhs); 

You need to look that up for each operator if you would like to comply with the usual patterns (and you should). Start here: Operator overloading

As pointed out by Ed S. return value optimization also applies (even before C++11) meaning that often object you return need neither be copied or moved.

So, this is now the way to return stuff:

std::string getstring(){ 
   std::string foo("hello");
   foo+=" world";
   return foo;
}

The fact that I made a foo object here is not my point, even if you did just do return "hello world"; this is the way to go.

And one more thing - if the pointer turns to be a vector, how can I find out its size after returned? And if it's impossible, as I think it is, how should I proceed to correctly return an array without this limitation?

The same goes for all copyable or movable types in the standard (these are almost all types, for example vectors, sets, and what not), except a few exceptions. For example std::arrays do not gain from moving. They take time proportional to the amount of elements. There you could return it in a unique_ptr to avoid the copy.

typedef std::array<int,15> MyArray;
std::unique_ptr<MyArray> getArray(){ 
  std::unique_ptr<MyArray> someArrayObj(new MyArray());
  someArrayObj->at(3)=5;
  return someArrayObj;
}

int main(){
  auto x=getArray();
  std::cout << x->at(3) <<std::endl; // or since we know the index is right: (*x)[3]
}

Now, to avoid ever writing new anymore (except for experts in rare cases) you should use a helper function called make_unique. That will vastly help exception safety, and is as convenient:

std::unique_ptr<MyArray> getArray(){ 
  auto someArrayObj=make_unique<MyArray>();
  someArrayObj->at(3)=5;
  return someArrayObj;
}

For more motivation and the (really short) implementation of make_unique, have a look here: make_unique and perfect forwarding

Update

Now make_unique is part of the C++14 standard. If you don't have it, you can find and use the whole implementation from the proposal by S.T.L.:

Ideone example on how to do that

like image 72
Johan Lundberg Avatar answered Sep 20 '22 16:09

Johan Lundberg


In C++, should my method return an object or a pointer to an object?

You should return an object by default. Usual exceptions are functions that return a subclass of a given class, and when returning nothing is a legal option for a function1.

What if it's an operator?

Operators return references or objects; although it is technically possible to return pointers from overloaded operators, it is not usually done.

And one more thing - if the pointer turns to be a vector, how can I find out it's size after returned?

I think you meant an array rather than a vector, because std::vector has a size() member function returning the size of the vector. Finding the size of a variable-length array is indeed not possible.

And if it's impossible, as I think it is, how should I proceed to correctly return an array without this limitation?

You should use std::vector, it does not limit you on the size or the type of elements that go into it.


1 In which case you return NULL or nullptr in C++11.
like image 36
Sergey Kalinichenko Avatar answered Sep 24 '22 16:09

Sergey Kalinichenko