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

后端 未结 4 987
不思量自难忘°
不思量自难忘° 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:42

    Firstly, if the constructor throws and the class is not trivially destructible then you have a problem, since the shared_ptr "wants" to delete it, which would provoke UB.

    So you must deal with that, either by using a nothrow constructor or by catching any exception and preventing the smart pointer from deleting the object. Since shared_ptr doesn't have a release() function, that's easier said than done. You could call terminate() if all else fails, but that won't make you popular with your users.

    If there are no other references to the object, then it will work provided that the class has no const or reference non-static data members (including members-of-members). The reason is 3.8/7:

    If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object ... can be used to manipulate the new object, if ... the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type ...

    Note that the shared_ptr holds just such a pointer, which it will use to manipulate the new object, which is UB if any of the conditions in 3.8/7 is broken. The only one that might be broken is this one, you've covered the rest with what you've said about your code. In particular, it's required that you created the original object as an instance of BigData, not a class derived from BigData, because the new object is required to have the same most-derived type as the old one.

    There are usually more robust ways to reset an object than this. For example, implement operator= (copy- or move assignment operator) and then write *bigDataPtr = BigData(). Of course that might not be quite as fast.

提交回复
热议问题