Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
312 views
in Technique[技术] by (71.8m points)

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

Let's say I have a class.

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

Then I do:

BigDataPtr bigDataPtr(new BigData());

Later on after I am done with my object and I am sure there no other users for the object.

Is it safe to do the following:

bigDataPtr->~BigDataPtr();
new (&*bigDataPtr) BigData;

Would this let me reset the object without any additional allocations?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...