Tho*_*ews 8 c++ boost copy-on-write shared-ptr
我在网上搜索并阅读了Boost文档shared_ptr.在SO上有一个响应,表示shared_ptr对于写入时复制(COW)糟透了,TR!并且已将其从字符串库中删除.关于SO的大多数建议都说使用shared_ptr而不是常规指针.
该文档还讨论了使用std::unique()COW指针,但我没有找到任何示例.
是否有关于为您执行COW的智能指针或让您的对象使用新shared_ptr的克隆对象然后修改克隆对象的讨论?
struct Nutrients;
struct Ingredient
{
Ingredient(const std::string& new_title = std::string(""))
: m_title(new_title)
{ ; }
std::string m_title;
Nutrients ing_nutrients;
};
struct Milk : public Ingredient
: Ingredient("milk")
{ ; }
struct Cream : public Ingredient
: Ingredient("cream")
{ ; }
struct Recipe
{
std::vector< boost::shared_ptr<Ingredient> > m_ingredients;
void append_ingredient(boost::shared_ptr<Ingredient> new_ingredient)
{
m_ingredients.push_back(new_ingredient);
return;
}
void replace_ingredient(const std::string& original_ingredient_title,
boost::shared_ptr<Ingredient> new_ingredient)
{
// Confusion here
}
};
int main(void)
{
// Create an oatmeal recipe that contains milk.
Recipe oatmeal;
boost::shared_ptr<Ingredient> p_milk(new Milk);
oatmeal.add_ingredient(p_milk);
// Create a mashed potatoes recipe that contains milk
Recipe mashed_potatoes;
mashed_potatoes.add_ingredient(p_milk);
// Now replace the Milk in the oatmeal with cream
// This must not affect the mashed_potatoes recipe.
boost::shared_ptr<Ingredient> p_cream(new Cream);
oatmeal.replace(p_milk->m_title, p_cream);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
令人困惑的是如何oatmeal用奶油代替食谱中的"牛奶" 而不影响mashed_potatoes配方.
我的算法是:
locate pointer to `Milk` ingredient in the vector.
erase it.
append `Cream` ingredient to vector.
Run Code Online (Sandbox Code Playgroud)
COW指针将如何在这里发挥作用?
注意:我在Windows NT,Vista和7上使用MS Visual Studio 2010.
Mat*_* M. 13
这里有几个问题捆绑在一起,所以如果我没有按照你期望的顺序解决这些问题,请耐心等待.
关于SO的大多数建议都说使用shared_ptr而不是常规指针.
是和否.不幸的是,SO的一些用户建议shared_ptr好像它是解决所有内存管理相关问题的银弹.事实并非如此.大多数建议谈论不使用裸指针,这是完全不同的.
真正的建议是使用智能管理:无论是智能指针(unique_ptr,scoped_ptr,shared_ptr,auto_ptr),智能集装箱(ptr_vector,ptr_map)或难题定制的解决方案(基于Boost.MultiIndex的,使用侵入性计数器,等...).
您应该根据需要选择要使用的智能管理器.最值得注意的是,如果您不需要共享对象的所有权,那么您不应该使用shared_ptr.
什么是COW?
COW(Copy-On-Write)是关于共享数据以"保存"内存并使副本更便宜......而不改变程序的语义.
从用户的角度来看,无论是否std::string使用COW无关紧要.修改字符串时,所有其他字符串不受影响.
COW背后的想法是:
看起来很相似
shared_ptr,为什么不呢?
它是相似的,但两者都是为了解决不同的问题,因此它们略有不同.
问题在于,shared_ptr无论是否共享所有权,都意味着无缝运行,COW很难实施"如果唯一所有者"测试.值得注意的是,相互作用weak_ptr使其变得困难.
显然,这是可能的.关键是不要泄漏shared_ptr,而不是使用weak_ptr(无论如何它们对COW都没用).
有关系吗 ?
不,不是真的.事实证明,COW并不是那么棒.大多数时候它是微观优化......并且一次微观悲观化.您可以节省一些内存(尽管它只在您不复制大型对象时才有效),但是您使算法复杂化,这可能会降低执行速度(您正在引入测试).
我的建议是不要使用COW.而且不要使用它们shared_ptr.
在个人情况下,我要么:
boost::ptr_vector<Ingredient>而不是std::vector< boost::shared_ptr<Ingredient> >(你不需要分享)IngredientFactory,创造(和管理)成分,并返回一个Ingredient const&,Factory应该比任何更长寿Receipt.编辑:按照Xeo的评论,似乎最后一项(IngredientFactory)是非常简洁的......
在这种情况下IngredientFactory,Receipt对象将包含一个std::vector<Ingredient const*>.注意原始指针:
Receipt 不对内存负责,但可以访问它Receipt对象使用原始(裸)指针是好的,只要你像对待它一样对待它们.您只需要注意潜在的无效性,并且如果您愿意,您可以重新安装它们 - 并且您相信提供者可以处理生命周期/内存管理方面的问题.
| 归档时间: |
|
| 查看次数: |
3421 次 |
| 最近记录: |