处理可能不指向任何东西的指针

Dealing with pointers that may not point to anything

本文关键字:任何东 指针 处理      更新时间:2023-10-16

在管理器中有一组指向其基类指针的vector对象:

std::vector<object*> objectVec;

类可能希望在管理器中使用Add()方法生成这些对象中的一个。问题是,它们随后需要自己设置或更新这些对象。我决定让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,如果这个对象被删除?或者可以使用某种智能指针来解决这个问题?问题是,我不需要使用智能指针来处理内存泄漏的可能性,而是要处理存储的指针失效的情况。

如果我没有讲清楚,或者问题形式不好,请让我知道。

是的,你可以在你的vector中存储智能ptr而不是原始ptr。在这种情况下,如果有人释放了一个对象,直到最后一个引用没有被释放(在你的例子中是vector中的引用),它才会被删除。您可以使用boost::shared_ptrstd::shared_ptr (c++ 11)。

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

您可能需要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++保持了这个功能。

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

天哪,看来其他人都比我先找到答案了…

最好是忘记这个"经理"的想法,但无论你是否这样做,共享所有权的解决方案始终是一样的,使用boost::shared_ptr

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

考虑到shared_ptr的所有权问题已经得到了解决,然后问自己,"经理"管理的是什么?

干杯,hth。

是我的责任,以确保whateverclass::objectptr总是设置为NULL,如果这个对象被删除?

你在写这个类,所以由你来决定。这是一个设计决策,任何一种选择都是允许的,只要您文档它:

  1. 设计应用
  2. 编写文档/规范
  3. 编写代码以匹配规范

或者可以使用某种智能指针来处理这个问题?

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

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类的用例。

悬空指针和内存泄漏是两个不同的问题,但是适当的共享指针可以避免这两个问题。对于这种特殊情况,我建议使用boost::shared_ptr

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

如果您有不同的要求,您可以在保存指针的位置之一(vector或对象)使用boost::weak_ptr

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

这是所有这些概念的文档