开发者

The .reset() method of common smart pointers

It seems to me that the reset method in the boost scoped_ptr and shared_ptr lead to incorrect order of construction and destruction:

boost::scoped_ptr<Component> component(GetDefaultComponent());
component.reset(new BetterComponent); // 1. Creation of the new object
                                      // 2. Destruction of the old object

This is the wrong order IMO.

It is possible to first call the reset method without arguments and then set the new pointer. However that seems lik开发者_StackOverflowe a workaround to me. (And it being a "workaround" implies that there is something wrong.)

I am convinced that the boost people are very smart. So there must have been a rationale for the current approach.

Does anyone know more?


It's absolutely the right order. What happens if new BetterComponent throws? Whoops. This is the same order in which everything happens, it's known as copy-and-swap, and it's the best way to go.

Especially since you didn't actually give any reason that the current order is wrong.


You can always refactor this in a free function (and do beware of the exception-safety consequences):

template<typename T, typename Pointer, typename... U>
void
emplace_reset(Pointer& pointer, U&&... u)
{
    pointer.reset();
    pointer.reset(new T(std::forward<U>(u)...));
}
// use as: emplace_reset<BetterComponent>(component);

But this is not a workaround because the reset member does just as advertised. What you're asking for is a new functionality.

A possible rationale for not providing the functionality you want (beyond exception-safety/transactional semantics) is that pointers have never, ever created the objects they point to: the constructors assume ownership but that's it. reset is consistent in that manner.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜