处理可能不指向任何内容的指针

发布于 2024-12-02 23:46:06 字数 701 浏览 0 评论 0 原文

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

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 返回的指针将指向垃圾。

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

如果我不清楚,或者问题格式错误,请告诉我。

任何帮助将不胜感激。

I have a set of objects in a vector of pointers to their baseclass held inside a manager:

std::vector<object*> objectVec;

Classes may wish to spawn one of these objects using the Add() method in the manager. The problem is that they then subsequently need to set or update these objects themselves. I've decided to have Add() return a pointer to the object itself, which is stored in whatever class has decided to spawn one. The problem is dealing with the case where the object behind that pointer may have been deleted.

Add looks like this:

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

and used like this:

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

Where objectptr is a member of whatever class has called the function. So should that particular object be deleted, the pointer returned by Add would point to rubbish.

Is it my responsibility to ensure that whateverclass::objectptr is always set to NULL if this object is deleted? Or can this be dealt with using some sort of smart pointer? The problem being that I don't need to use a smart pointer to deal with the possibility of a memory leak, but to deal with the case where the stored pointer has become invalid.

Please let me know if i've been unclear, or if the question is badly formed.

Any help would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

醉生梦死 2024-12-09 23:46:06

是的,您可以在向量中存储智能 ptr 而不是原始 ptr。在这种情况下,如果有人释放一个对象,则直到最后一个引用未释放为止(在您的情况下保存在向量中的引用),该对象才会被删除。您可以使用 boost::shared_ptrstd::shared_ptr (C++11)。

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

Yes, you can store smart ptr's instead of raw ptr's in your vector. In this case if somebody releases an object, it's not deleted until the last reference is not released (the one held in vector in your case). You can use boost::shared_ptr or std::shared_ptr (C++11).

If this is not what you want, you can use boost::weak_ptr to store references in your vector. weak_ptr doesn't increment reference counter so if somebody releases an object, it's get deleted, but reference (weak_ptr) stored in your vector allows you to check this.

情话难免假 2024-12-09 23:46:06

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

这些课程带有 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

如果我没记错的话,在实现更新版本的编译器上的 std 命名空间中内置了等效项C++0x 标准。 Visual C++ 保留了此内置功能。

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

哦,天哪,看起来其他人都比我先一步 回答...

You likely want weak_ptr and shared_ptr. shared_ptr is a general smart pointer class. weak_ptr is an observer of shared_ptr. When all the references of the shared_ptr go away, instances of weak_ptr "become null" and are easier to deal with than a pointer to a deleted object.

These classes come with 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

And if I'm not mistaken, there are equivalents built into std namespace on compilers that implement newer C++0x standards. Visual C++ keeps has this built in.

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

Oh shoot, looks like everyone else beat me to the answer...

玉环 2024-12-09 23:46:06

最好的办法是忘记这个“管理器”的想法,但无论您是否这样做,共享所有权的解决方案都与往常相同,使用 boost::shared_ptr

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

考虑到使用 shared_ptr 已经解决了所有权问题,那么问问自己,“管理器”管理什么?

干杯&呵呵,,

Best is to forget this "manager" idea, but if you do or if you don't, the solution to shared ownership is the same as always, use boost::shared_ptr.

Or, with relatively new compiler, use std::shared_ptr.

Considering that with shared_ptr the ownership issue is taken care of already, then ask yourself, what is it that the "manager" manages?

Cheers & hth.,

七月上 2024-12-09 23:46:06

如果删除此对象,我是否有责任确保 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 类的用例。认为“编写一次,多次使用”。

Is it my responsibility to ensure that whateverclass::objectptr is always set to NULL if this object is deleted?

You're writing the class, so it's up to you to decide. This is a design decision and either choice is admissible, provided that you document it:

  1. design the application
  2. write the documentation/specification
  3. write the code to matches the specification

Or can this be dealt with using some sort of smart pointer?

Using a smart pointer (strong or weak version) will help achieve whatever behavior you chose for the class. However, it will also strongly affect the client code. In the following code:

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;
};

The use cases for the ObjectManager class should be taken into consideration, on top of simplicity of implementation. Think "write once, use a lot".

下壹個目標 2024-12-09 23:46:06

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

使用 std::vector> 作为向量类型,并且持有裸指针的对象现在也持有 boost::shared_ptr。这将确保只要这些对象之一仍然存在,指针在向量和对象中就保持有效。

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

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

这里是所有这些概念的文档。

Dangling pointers and memory leaks are two different issues, but a proper shared pointer can protect from both. For this particular case, I'd suggest boost::shared_ptr.

Use std::vector<boost::shared_ptr<BaseType>> for the vector type and also have the objects that hold the bare pointers now hold instead a boost::shared_ptr<BaseType>. This will ensure that the pointers will stay valid in the vector and in the objects as long as one of those objects still exist.

If you have differing requirements, you can use a boost::weak_ptr in one of the places holding the pointer (either the vector or the object).

Also, the object can hold a derived type instead of a base type (boost::shared_ptr<DerivedType>) and you can convert between them using boost::shared_static_cast.

Here is the documentation for all of these concepts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文