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.