Destruction object reference before use

I would like to create an object using

object().addSomething().addSomethingElse()

      

and then use it in a piece of code, but the following code won't work:

class myObj {
public:
 myObj() {}
 ~myObj() { std::cout << "dtor called" << std::endl; }
 myObj& someOtherOperation() {
  return *this;   
 }
};

int main() {
    auto& elementRef = myObj().someOtherOperation();
    {
        std::cout << "some stuff that uses elementRef" << std::endl;
    }  
}

      

the destructor is called before the part of the code that uses the reference.

I would like to avoid an expensive object copy operation and keep

object().addSomething().addSomethingElse()

      

but it seems the links don't allow it. Any solutions for this?

+3


source to share


4 answers


Create the object yourself:

auto o = myObj();

      



and then use it loosely:

o.someOtherOperation().someOtherOperation();

      

+6


source


You can optimize using move semantics when the implicit object parameter is rvalue:

myObj someOtherOperation() & {
    return *this;   
}

myObj someOtherOperation() && {
    return std::move(*this);   
}

      



An example of the difference:

auto element = myObj().someOtherOperation(); //uses move semantics
myobj obj;
auto otherElement = obj.someOtherOperation(); //doesn't use move semantics

      

+1


source


Yes, there is a special exception that allows you to extend the lifetime of time series if they are linked to links, but when this anchor is hidden through a function, it does not and cannot work. int main()

can be defined in a completely separate translation unit where he doesn't even see the body someOtherOperation()

.

You should *this

only return by reference if you have an lvalue.

myObj& someOtherOperation() & {
// -------------------------^--
  ...
  return *this;   
}

      

You can return by value by moving from *this

when your method is called on an rvalue:

myObj someOtherOperation() && {
// ------------------------^^--
  someOtherOperation(); // keep implementation in other overload
  return std::move(*this);
}

      

+1


source


You can get an "extension" of life if you return an object and bind it to a link i.e.

const Obj& foo = func_returning_an_instance();

      

in this case, the instance is guaranteed to live as long as the link.

If, however, your method returns a link , the expansion of the binding object is not done ... so in

const Obj& r = Obj().ref_retuning_method().ref_returning_method();

      

the expression will evaluate correctly (i.e. the instance Obj

will live long enough to evaluate the full expression, which allows the reference returned by the first call to be returned for the second call), but the object will expire its life immediately after the reference is initialized r

, and won't be legally used afterwards r

...

+1


source







All Articles