在std :: map中使用boost智能指针

时间:2012-12-10 04:27:21

标签: c++ memory-management boost shared-ptr stdmap

在我最新的C ++内存管理方面,我一直在使用智能指针。部分原因是我使用一系列映射将字符串绑定到类(称为IBlockInput),将类绑定到“context”中的当前值。我看到两个选项,但两者都有同样的问题:

选项1 :类的当前值存储在类中,按上下文排序

选项2 :类的当前值存储在上下文中,按类排序

这里的问题是任何一个物体都可能在另一个物体之前死亡。当所有输入保持不变或者在上下文保持时可以销毁输入时,可以销毁上下文。当一个人死亡时,需要为其释放资源。到目前为止我所使用的是(使用选项2):

std::map<std::string, boost::weak_ptr<IBlockInput> > inputs;
std::map<boost::weak_ptr<IBlockInput>, boost::shared_ptr<std::vector<double> > > inputValues;

他们需要像这样分开的原因是其他类(IOutputBlocks)需要根据指针访问和设置IInputBlocks的值。

我对此有几个问题:

问题1 :我可以像普通地图一样访问inputValues地图,只需传入指针(不是boost :: shared_ptr / boost :: weak_ptr ... T *)来访问它?我可以使用weak_ptrs或shared_ptrs,如果这是实际的方法

问题2 :我正在使用弱指针让对象在需要时死掉(如果我在做上面的选项1,我将不得不指向上下文的弱指针)。如果弱指针到期并且我尝试在地图中访问它会发生什么?它指向的数据是否已丢失或者是否仍然使用原始指针?

问题3 :也许更好的方法是使用原始指针作为键/值,然后使用弱指针(用于实时检查各种类型)的补充地图,如这样:

std::map<std::string, IBlockInput*> inputs;
std::map<IBlockInput*, boost::shared_ptr<std::vector<double> > inputValues;
std::map<IBlockInput*, boost::weak_ptr<IBlockInput> > pointerCache;

然后我可以使用pointerCache进行“实时检查”,看看我是否应该保持双打矢量并以这种方式管理内存。 注意:输入向量经常刷新。

推荐的做法是什么?我很擅长提升和使用智能指针(过去几个月我一直在工作中受到C#的呵护,不必担心关于这种事情。)

1 个答案:

答案 0 :(得分:0)

std::map<boost::weak_ptr<IBlockInput>, boost::shared_ptr<std::vector<double> > > inputValues; - 这很糟糕。当weak_ptr死亡时,它将等于nullptr,并且不会维持其顺序。您将获得未定义的行为(实际上,无限循环和崩溃)

请注意std::map s。

中用于键的内容

使用可能被解除分配的原始指针是不好的,因为ABA问题,有效指针变为无效,然后新指针被分配等于它。 (正在利用make_shared的实施细节来使这种事情在实践中发挥作用,但这是混乱和危险的)

你可能需要某种双重间接,你可以使用与指针相同的指针。我会称他们为句柄。句柄到期的内部指针使它取消注册地图中的句柄,当它超出每个地图时它会自行销毁。我不知道它是否会起作用,但它可能会起作用。我怀疑它首先需要一些摆弄。

句柄将按其(外部)指针值排序,因此将保持排序。要确定句柄是否有效,您必须同时检查外部和内部指针的有效性(因此非空句柄可能对“取消引用”无效)。

但我想不出办法让这个干净。