How to "Return an Object" in C++

How to return an object in C++?

I don't want to return a copied value because it's inefficient

Prove it.

Look up RVO and NRVO, and in C++0x move-semantics. In most cases in C++03, an out parameter is just a good way to make your code ugly, and in C++0x you'd actually be hurting yourself by using an out parameter.

Just write clean code, return by value. If performance is a problem, profile it (stop guessing), and find what you can do to fix it. It likely won't be returning things from functions.


That said, if you're dead set on writing like that, you'd probably want to do the out parameter. It avoids dynamic memory allocation, which is safer and generally faster. It does require you have some way to construct the object prior to calling the function, which doesn't always make sense for all objects.

If you want to use dynamic allocation, the least that can be done is put it in a smart pointer. (This should be done all the time anyway) Then you don't worry about deleting anything, things are exception-safe, etc. The only problem is it's likely slower than returning by value anyway!

Best way to return an object in c++?

You need to adjust the Channel class itself so that it isn't copyable. If it is copyable, the user can copy it, and nothing you do can prevent it.

If copying is not a meaningful operation, then you can "disable" it. Simply define the copy constructor (Channel(const Channel&)) and the assignment operator (Channel& operator=(const Channel&)) to be private. Then any attempt at copying the class will result in a compile error.

On a side note, as others have mentioned, C++ is not the scripting languages you're familiar with. Everything is not a reference, and you're only setting yourself up for a world of pain by pretending otherwise. In C++, it is common to allocate objects on the stack, and pass objects by value, rather than passing references and pointers around.

How to return a class object by reference in C++?

You're probably returning an object that's on the stack. That is, return_Object() probably looks like this:

Object& return_Object()
{
Object object_to_return;
// ... do stuff ...

return object_to_return;
}

If this is what you're doing, you're out of luck - object_to_return has gone out of scope and been destructed at the end of return_Object, so myObject refers to a non-existent object. You either need to return by value, or return an Object declared in a wider scope or newed onto the heap.

What is the proper way to return an object from a C++ function?

Modern compilers typically implement the (Named) Return Value Optimization, by which the copy you reference (and would logically expect) is not done.

Ever since Visual Studio 2005 (VC++ 8.0) I don't think twice about returning objects.

Returning C++ Object - Best Practice

Solution 1 does not use the copy constructor but return value optimization. It means that the object constructed in the function is actually not copied but passed to the caller of the function directly. Solution 1 is a very good option which I would recommend for non-polymorphic objects (i.e. no inheritance) which do not use too much space on the stack.

The preferred method for polymorphic objects would be Solution 2. But always think about who owns your objects, i.e. who is responsible for calling delete. A good alternative is using shared_ptr or unique_ptr.

Solution 3 does not really create the object, it only works with it once it is already created. It also does not make sense to return the object here.

how to return an object in c#?

You should define the return type and return the instance.

public static ArasTEST aras()
{
// insert code here...


return ArasOrder;
}

Ways to return an object in C++ method

From what I've learned about C++ so far, I think getAnimal currently returns a copy of the animal, not a reference like in Java.

Correct.

I've seen this suggested as the correct way to go about returning objects

If you intend to return a copy, then yes.

I'd just be changing the copy of it and the actual animal inside of MyAnimals.animals would remain unchanged.

Correct.

One way I've seen to get around this is to return Animal& instead of Animal, and that seems to work for the most part

Yes, references are exactly what you need for that.

but what if I want to reassign the variable the was assigned to that returned Animal?

Well, typically there is no need to do re-assign an existing reference (which is not allowed anyway). Instead of what you did, you could do:

Animal& a = myanimals.getAnimal(1);
Animal& b = myanimals.getAnimal(2);

If you for some reason need to, then use a pointer instead, to get around the limitation. You can do this even when you return a reference:

Animal* a = &myanimals.getAnimal(1);
a = &myanimals.getAnimal(2);

Returning an object in C++

This question will probably be closed as a duplicate. It is an oft-asked question. However I would like to answer it anyway.

In C++11, when you are the client of an object like std::string, you should pass it around by value and not worry so much about efficiency:

std::string getStr(){
return "Hello";
}

std::string hello = getStr();

At this level you do not need to be concerned with rvalue references. Just know that std::string can "copy" from rvalues (such as the return from getStr()) very efficiently. This "copy" is actually called a "move" and is enabled automatically because you are copying from an rvalue (an anonymous temporary).

Don't try to optimize copying by reverting to reference counting. Only use reference counting if you need shared ownership semantics. This statement isn't always true. But for learning the basics, it is close enough that it is a good rule of thumb to follow.

You need to start worrying about rvalue references when you design your class that needs to be passed around by value:

class Widget
{
// pointer to heap data
public:
// ...
};

For a brief introduction to rvalue references and move semantics, N2027 is a decent tutorial. N2027 is too long to be pasted in here, but short enough to be an easy read. std::string follows the basics laid down in N2027 to enable you to pass it around by value guilt free. And you can follow those same design patterns in your Widget.

Return a named object of a class from a function (by value ) and implicit move rule?

The behavior of your program can be understood with the help of Automatic move from local variables and parameters:

If expression is a (possibly parenthesized) id-expression that names a variable whose type is either

  • a non-volatile object type or

  • a non-volatile rvalue reference to object type (since C++20)

and that variable is declared

  • in the body or

  • as a parameter of

    the innermost enclosing function or lambda expression,

then overload resolution to select the constructor to use for initialization of the returned value or, for co_return, to select the overload of promise.return_value() (since C++20) is performed twice:

  • first as if expression were an rvalue expression (thus it may select the move constructor), and
  • if the first overload resolution failed or
  • it succeeded, but did not select the move constructor (formally, the first parameter of the selected constructor was not an rvalue reference to the (possibly cv-qualified) type of expression) (until C++20)
  • then overload resolution is performed as usual, with expression considered as an lvalue (so it may select the copy constructor).

Now, lets apply this to your code snippet on case by case basis.

Example 1

In this case, as the move ctor is available and viable, the condition "first as if expression were an rvalue expression" is satisfied and hence the move ctor is selected we get the mentioned output.

class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test( const test& z) {
printf(" test( const test&z)\n");
}
test(test&& s)noexcept{
printf(" test(test&& s)\n");
}
test& operator=(test e) {
printf(" test& operator=( test e)\n");
return *this;
}
};
test Some_thing() {
test i;
return i;
}
int main()
{
Some_thing();
return 0;
}


Example 2

In this case, since you've provided the copy ctor test::test( test&), the compiler will not synthesize a move ctor for us. Note that not having a synthesized move ctor is different from having a deleted move ctor. Thus the condition "if the first overload resolution failed" is satisfied(because there is no move ctor) and the overload resolution is then performed for the second time which will now select the provided copy ctor and hence the mentioned output.

class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test( test& z) {
printf(" test( test&z)\n");
}
test& operator=(test e) {
printf(" test& operator=( test e)\n");
return *this;
}
};
test Some_thing() {
test i;
return i;
}
int main()
{
Some_thing();
return 0;
}


Example 3

In this case, you've explicitly deleted the move ctor. That is, your intent is that if someone tried to use the move ctor, then it should fail. So here, when the overload resolution happens for the first time, the move ctor is selected but since you've explicitly marked it as deleted fails immediately and hence the error.

class test {
public:
test(test&& z) = delete;
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test( const test& z) {
printf(" test( test&z)\n");
}
test& operator=(test e) {
printf(" test& operator=( test e)\n");
return *this;
}
};
test Some_thing() {
test i;
return i;
}
int main()
{
Some_thing();
return 0;
}


Related Topics



Leave a reply



Submit