【问题标题】:Test, if object was deleted测试,如果对象被删除
【发布时间】:2010-05-03 12:37:30
【问题描述】:

请看下面的代码:

class Node
{
private:
    double x, y;
public:
    Node (double xx, double yy): x(xx), y(yy){}
};

int main()
{
  Node *n1 = new Node(1,1);
  Node *n2 = n1;

  delete n2; 
  n2 = NULL;

  if (n1 != NULL) //Bad test
  {
     delete n1;   //throw an exception
  }
}

有两个指针n1、n2指向同一个对象。我想使用 n1 指针测试来检测 n2 是否被删除。但是这个测试导致异常。

有什么方法可以使用 n1 指针确定对象是否被删除(或未被删除)?

【问题讨论】:

    标签: c++ object testing delete-operator


    【解决方案1】:

    据我所知,处理这种情况的典型方法是使用引用计数指针,就像(例如)COM 那样。在 Boost 中,有一个 shared_ptr 模板类可以提供帮助 (http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/shared_ptr.htm)。

    【讨论】:

    • +1: boost::shared_ptr 真的很有效。您甚至不必自己调用 delete,并且可以为指向的值提供自己的析构函数。
    【解决方案2】:

    没有。您的代码中没有任何方法可以到达 n1 指针并在指向的对象被销毁时更改它。

    为此,Node 必须(例如)维护指向它的所有指针的列表,并且每次复制指针值时都必须手动注册(即调用方法)。工作起来会很痛苦。

    【讨论】:

      【解决方案3】:

      当您拥有一个对象时,它将位于内存中的某个位置。这是n1 和n2 的值。当您删除对象时,通过释放该对象使用的内存,该内存是无效的。因此,如果 n1 指向的任何内容被删除,您将永远无法访问它。

      我建议创建一个包装对象,其中包含一个计数器和一个指向该对象的指针。当你想指向实际对象时,你必须指向包装器,而当你想删除对象时,实际上是调用包装器上的一个方法:

      如果要指向对象,则应增加包装器的计数器,并指向包装器。如果要删除对象,则应减少计数器并将指向包装器的指针设置为 null。如果包装器的计数器达到零,您可以安全地删除实际对象,然后删除包装器。

      【讨论】:

      • I suggest creating a wrapper object, which contains a counter and a pointer to the object. - 这叫共享指针,为什么要重新发明轮子?
      猜你喜欢
      • 2011-08-13
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2021-09-16
      • 2014-08-28
      相关资源
      最近更新 更多