Can I use placement new to reset an object within a shared_ptr?

后端 未结 4 976
不思量自难忘°
不思量自难忘° 2020-12-16 22:54

Let\'s say I have a class.

class BigData {...};
typedef boost::shared_ptr BigDataPtr; 

Then I do:

BigDataPt         


        
4条回答
  •  生来不讨喜
    2020-12-16 23:48

    There are a few ways to go about this. You can use placement new, and this is guaranteed to be safe for two reasons:

    1. You have already allocated the memory for the object, so you know it’s sized and aligned correctly.

    2. shared_ptr is non-invasive; its sole responsibility is to count references and call the deleter when necessary.

    However, consider what can happen if reconstruction of the object fails—i.e., throws an exception:

    bigDataPtr->~BigDataPtr();
    new (bigDataPtr.get()) BigData;
    

    Then you have a problem: the deleter can be called on a non-constructed object, leading almost certainly to undefined behaviour. I say “almost” because the deleter could be a no-op, in which case all would be well.

    Safer, I think, would be to move a new value into the existing object:

    *bigDataPtr = BigData(42);
    

    Or add a reset() member function to BigData:

    bigDataPtr->reset(42);
    

    Then it’s explicit what your real intent is, and you don’t need to be as concerned about object lifetimes.

提交回复
热议问题