2010-05-03 79 views
4

看看下面的代码,请:测试,如果对象被删除

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指针?

回答

4

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

为了达到这个目的,Node必须(例如)维护一个指向它的所有指针的列表,并且每次复制指针值时都必须手动注册(即调用一个方法)。合作会很痛苦。

11

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

+2

+1:boost :: shared_ptr真的很有效率。你甚至不需要自己调用delete,并且可以为所指向的值提供你自己的析构函数。 – ereOn 2010-05-03 12:50:30

0

当你有一个对象时,它会在内存中的某个地方。这是n1n2的值。当你删除对象时,通过释放对象使用的内存,内存无效。所以你永远不能访问任何n1点,如果它被删除。

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

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

+1

'我建议创建一个包装对象,它包含一个计数器和一个指向该对象的指针。“ - 这称为共享指针,为什么重新发明轮子? – 2012-12-07 08:50:16

相关问题