Nat*_*mal 8 c++ memory performance
假设我有一堂课.
class BigData {...};
typedef boost::shared_ptr<BigData> BigDataPtr;
Run Code Online (Sandbox Code Playgroud)
然后我做:
BigDataPtr bigDataPtr(new BigData());
Run Code Online (Sandbox Code Playgroud)
在我完成了我的对象之后,我确信没有其他用户使用该对象.
执行以下操作是否安全:
bigDataPtr->~BigDataPtr();
new (&*bigDataPtr) BigData;
Run Code Online (Sandbox Code Playgroud)
这会让我重置对象而不需要任何额外的分配吗?
有几种方法可以解决这个问题.您可以使用新的展示位置,这可以保证安全,原因有两个:
您已经为对象分配了内存,因此您知道它的大小和对齐方式正确.
shared_ptr是非侵入性的; 它的唯一责任是计算参考资料并在必要时致电删除者.
但是,请考虑如果对象的重建失败会发生什么 - 即抛出异常:
bigDataPtr->~BigDataPtr();
new (bigDataPtr.get()) BigData;
Run Code Online (Sandbox Code Playgroud)
然后你有一个问题:可以在非构造对象上调用删除器,几乎肯定会导致未定义的行为.我说"差不多",因为删除者可能是一个无操作,在这种情况下一切都会很好.
我认为更安全的是将新值移动到现有对象中:
*bigDataPtr = BigData(42);
Run Code Online (Sandbox Code Playgroud)
或者将reset()成员函数添加到BigData:
bigDataPtr->reset(42);
Run Code Online (Sandbox Code Playgroud)
然后它明确你的真实意图是什么,你不需要关心对象的生命周期.
是的,通常是安全的。 (致敬马克西姆·叶戈鲁什金(Maxim Yegorushkin)对边缘案例的观察)
请注意下面的拼写错误消息
Boost 将解引用和->运算符定义为
template<class T>
typename boost::detail::sp_dereference< T >::type boost::shared_ptr< T >::operator* () const;
template<class T>
typename boost::detail::sp_member_access< T >::type boost::shared_ptr< T >::operator-> () const;
Run Code Online (Sandbox Code Playgroud)
当这些detail位得到解决后,你就得到了这个
template<class T>
T & boost::shared_ptr< T >::operator* () const
template<class T>
T * boost::shared_ptr< T >::operator-> () const
Run Code Online (Sandbox Code Playgroud)
所以你直接处理指向的对象。没有代理或其他结构可能会干扰您正在尝试的操作。
就指向的数据而言,您的代码:
bigDataPtr->~BigDataPtr();
new (&*bigDataPtr) BigData;
Run Code Online (Sandbox Code Playgroud)
可能有错别字。但如果你打算:
bigDataPtr->~BigData();
new (&*bigDataPtr) BigData;
Run Code Online (Sandbox Code Playgroud)
它将决心
(BigData pointer)->~BigData();
new (&(BigData reference)) BigData;
Run Code Online (Sandbox Code Playgroud)
这是合法的,并且您是正确的,它可以避免分配时通常产生的额外分配。