处理可能不指向任何事物的指针

时间:2011-09-06 16:22:55

标签: c++ smart-pointers

我在一个管理器内的基类的指针向量中有一组对象:

std::vector<object*> objectVec;

类可能希望使用管理器中的Add()方法生成其中一个对象。问题是他们随后需要自己设置或更新这些对象。我决定让Add()返回一个指向对象本身的指针,该指针存储在决定产生一个的任何类中。问题是处理指针后面的对象可能已被删除的情况。

添加如下所示:

object* ObjectManager::Add(object* obj)
{
   objectVec.push_back(obj);
   return objectVec.back();
}

并像这样使用:

objectptr = ObjectManager::OMan()->Add(new object());

其中objectptr是调用该函数的任何类的成员。因此,如果要删除该特定对象,Add返回的指针将指向垃圾。

如果删除此对象,是否有责任确保whateverclass :: objectptr始终设置为NULL?或者可以使用某种智能指针处理?问题是我不需要使用智能指针来处理内存泄漏的可能性,而是处理存储指针变为无效的情况。

如果我不清楚,或者问题是否形成错误,请告诉我。

非常感谢任何帮助。

5 个答案:

答案 0 :(得分:3)

是的,你可以在你的载体中存储智能ptr而不是原始ptr。在这种情况下,如果有人释放了一个对象,那么在最后一个引用未释放之前它不会被删除(在你的情况下,在向量中保存一个引用)。您可以使用boost::shared_ptrstd::shared_ptr(C ++ 11)。

如果这不是您想要的,您可以使用boost::weak_ptr在向量中存储引用。 weak_ptr不会增加引用计数器,所以如果某人释放了一个对象,它就会被删除,但是你的向量中存储的引用(weak_ptr)允许你检查它。

答案 1 :(得分:2)

你可能想要weak_ptr和shared_ptr。 shared_ptr是一般智能指针类。 weak_ptr是shared_ptr的观察者。当shared_ptr的所有引用消失时,weak_ptr的实例“变为null”并且比指向已删除对象的指针更容易处理。

这些课程附带Boost。 http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/shared_ptr.htm

http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/weak_ptr.htm

如果我没弄错的话,在实现更新的C ++ 0x标准的编译器上有std命名空间内置的等价物。 Visual C ++ keep内置了这个。

http://blogs.msdn.com/b/vcblog/archive/2011/02/16/10128357.aspx

哦,拍摄,看起来像其他人一样打败我的答案......

答案 2 :(得分:2)

最好是忘记这个“经理”的想法,但如果你这样做,或者如果你不这样做,共享所有权的解决方案就像往常一样,使用boost::shared_ptr

或者,使用相对较新的编译器,使用std::shared_ptr

考虑到shared_ptr所有权问题已经得到解决,那么问问自己,“经理”管理的是什么?

干杯&amp;第h。,

答案 3 :(得分:1)

  

如果此对象被删除,我是否有责任确保whateverclass::objectptr始终设置为NULL

你正在上课,所以由你来决定。这是一项设计决定,只要您记录它,就可以接受这两种选择:

  1. 设计应用程序
  2. 编写文档/规范
  3. 编写符合规范的代码
  4.   

    或者可以使用某种智能指针来解决这个问题吗?

    使用智能指针(强或弱版本)将有助于实现您为课程选择的任何行为。但是,它也会强烈影响客户端代码。在以下代码中:

    class Scene
    {
          // can't use this object in a call to `ObjectManager::Add()`,
          // assuming it uses a smart pointer to deal with object lifetimes.
        Object myLight;
    };
    

    除了实现的简单性之外,还应考虑ObjectManager类的用例。想想“写一次,多用”。

答案 4 :(得分:0)

悬空指针和内存泄漏是两个不同的问题,但正确的共享指针可以保护两者。对于这种特殊情况,我建议boost::shared_ptr

使用std::vector<boost::shared_ptr<BaseType>>作为矢量类型,并且现在保持裸指针的对象代替boost::shared_ptr<BaseType>。这将确保指针在vector和对象中保持有效,只要其中一个对象仍然存在。

如果您有不同的要求,可以在其中一个拿着指针的地方(boost::weak_ptr或对象)使用vector

此外,对象可以保存派生类型而不是基本类型(boost::shared_ptr<DerivedType>),您可以使用boost::shared_static_cast在它们之间进行转换。

Here is the documentation for all of these concepts.