How to “return an object” in C++?

后端 未结 8 535
礼貌的吻别
礼貌的吻别 2020-11-22 09:25

I know the title sounds familiar as there are many similar questions, but I\'m asking for a different aspect of the problem (I know the difference between having things on t

相关标签:
8条回答
  • 2020-11-22 09:32

    Just create the object and return it

    Thing calculateThing() {
        Thing thing;
        // do calculations and modify thing
         return thing;
    }
    

    I think you'll do yourself a favor if you forget about optimization and just write readable code (you'll need to run a profiler later - but don't pre-optimize).

    0 讨论(0)
  • 2020-11-22 09:36

    Firstly you have an error in the code, you mean to have Thing *thing(new Thing());, and only return thing;.

    • Use shared_ptr<Thing>. Deref it as tho it was a pointer. It will be deleted for you when the last reference to the Thing contained goes out of scope.
    • The first solution is very common in naive libraries. It has some performance, and syntactical overhead, avoid it if possible
    • Use the second solution only if you can guarantee no exceptions will be thrown, or when performance is absolutely critical (you will be interfacing with C or assembly before this even becomes relevant).
    0 讨论(0)
  • 2020-11-22 09:37

    Just return a object like this:

    Thing calculateThing() 
    {
       Thing thing();
       // do calculations and modify thing
       return thing;
    }
    

    This will invoke the copy constructor on Things, so you might want to do your own implementation of that. Like this:

    Thing(const Thing& aThing) {}
    

    This might perform a little slower, but it might not be an issue at all.

    Update

    The compiler will probably optimize the call to the copy constructor, so there will be no extra overhead. (Like dreamlax pointed out in the comment).

    0 讨论(0)
  • 2020-11-22 09:40

    I'm sure a C++ expert will come along with a better answer, but personally I like the second approach. Using smart pointers helps with the problem of forgetting to delete and as you say, it looks cleaner than having to create an object before hand (and still having to delete it if you want to allocate it on the heap).

    0 讨论(0)
  • 2020-11-22 09:42

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

    This may not be true. Compilers can do optimisation to prevent this copying.

    For example, GCC does this optimisation. In the following program, neither move constructor nor copy constructor are called, since no copying or moving is done. Also, notice the address of c. Even though the object c is instantiated inside the function f(), c resides in the stack frame of main().

    class C {
    public:
        int c = 5;
        C() {}
        C(const C& c) { 
            cout << "Copy constructor " << endl;
        }
        C(const C&& c)  noexcept {
            cout << "Move Constructor" << endl;
        }
    };
    
    C f() {
        int beforeC;
        C c;
        int afterC;
    
        cout << &beforeC << endl;   //0x7ffee02f26ac
        cout << &c << endl;         //0x7ffee02f2710 (notice: even though c is instantiated inside f(), c resides in the stack frame of main()
        cout << &afterC << endl;    //0x7ffee02f26a8
    
        return c;
    }
    
    C g() {
        C c = f(); ///neither copy constructor nor move constructor of C are called, since none is done
        cout << &c << endl;  //0x7ffee02f2710
        return c;
    }
    
    int main() {
        int beforeC;
        C c = g();    ///neither copy constructor nor move constructor of C are called, since none is done
        int afterC;
    
        cout << &beforeC << endl; //0x7ffee02f2718 
        cout << &c << endl;       //0x7ffee02f2710 (notice:even though c is returned from f,it resides in the stack frame of main)
        cout << &afterC << endl;  //0x7ffee02f270c
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-22 09:44

    Did you try to use smart pointers (if Thing is really big and heavy object), like auto_ptr:

    
    std::auto_ptr<Thing> calculateThing()
    {
      std::auto_ptr<Thing> thing(new Thing);
      // .. some calculations
      return thing;
    }
    
    
    // ...
    {
      std::auto_ptr<Thing> thing = calculateThing();
      // working with thing
    
      // auto_ptr frees thing 
    }
    
    0 讨论(0)
提交回复
热议问题