C++: returning by reference and copy constructors

后端 未结 9 1773
伪装坚强ぢ
伪装坚强ぢ 2020-12-09 09:46

References in C++ are baffling me. :)

The basic idea is that I\'m trying to return an object from a function. I\'d like to do it without returning a pointer (because

相关标签:
9条回答
  • 2020-12-09 10:01

    The best way to understand copying in C++ is often NOT to try to produce an artificial example and instrument it - the compiler is allowed to both remove and add copy constructor calls, more or less as it sees fit.

    Bottom line - if you need to return a value, return a value and don't worry about any "expense".

    0 讨论(0)
  • 2020-12-09 10:04

    If you create an object like this:

    MyClass foo(a, b, c);
    

    then it will be on the stack in the function's frame. When that function ends, its frame is popped off the stack and all the objects in that frame are destructed. There is no way to avoid this.

    So if you want to return an object to a caller, you only options are:

    • Return by value - a copy constructor is required (but the call to the copy constructor may be optimised out).
    • Return a pointer and make sure you either use smart pointers to deal with it or carefully delete it yourself when done with it.

    Attempting to construct a local object and then return a reference to that local memory to a calling context is not coherent - a calling scope can not access memory that is local to the called scope. That local memory is only valid for the duration of the function that owns it - or, another way, while execution remains in that scope. You must understand this to program in C++.

    0 讨论(0)
  • 2020-12-09 10:06

    read about RVO and NRVO (in a word these two stands for Return Value Optimization and Named RVO, and are optimization techniques used by the compiler to do what you're trying to achieve)

    you'll find a lot of subjects here on stackoverflow

    0 讨论(0)
  • 2020-12-09 10:07

    Recommended reading: Effective C++ by Scott Meyers. You find a very good explanation about this topic (and a lot more) in there.

    In brief, if you return by value, the copy constructor and the destructor will be involved by default (unless the compiler optimizes them away - that's what happens in some of your cases).

    If you return by reference (or pointer) a variable which is local (constructed on the stack), you invite trouble because the object is destructed upon return, so you have a dangling reference as a result.

    The canonical way to construct an object in a function and return it is by value, like:

    MyClass fun() {
        return MyClass(a, b, c);
    }
    
    MyClass x = fun();
    

    If you use this, you don't need to worry about ownership issues, dangling references etc. And the compiler will most likely optimize out the extra copy constructor / destructor calls for you, so you don't need to worry about performance either.

    It is possible to return by reference an object constructed by new (i.e. on the heap) - this object will not be destroyed upon returning from the function. However, you have to destroy it explicitly somewhere later by calling delete.

    It is also technically possible to store an object returned by value in a reference, like:

    MyClass& x = fun();
    

    However, AFAIK there is not much point in doing this. Especially because one can easily pass on this reference to other parts of the program which are outside of the current scope; however, the object referenced by x is a local object which will be destroyed as soon as you leave the current scope. So this style can lead to nasty bugs.

    0 讨论(0)
  • 2020-12-09 10:15

    You are stucked with either:

    1) returning a pointer

    MyClass* func(){ //some stuf return new MyClass(a,b,c); }

    2) returning a copy of the object MyClass func(){ return MyClass(a,b,c); }

    Returning a reference is not valid because the object is to be destroyed after exiting the func scope, except if the function is a member of the class and the reference is from a variable that is member of the class.

    0 讨论(0)
  • 2020-12-09 10:19

    Basically, returning a reference only makes sense if the object still exists after leaving the method. The compiler will warn you if you return a reference to something that is being destroyed.

    Returning a reference rather than an object by value saves copying the object which might be significant.

    References are safer than pointers because they have different symantics, but behind the scenes they are pointers.

    0 讨论(0)
提交回复
热议问题