一个对象可以释放它的记忆吗?

时间:2012-05-28 10:56:41

标签: c++ delete-operator

  

可能重复:
  C++: Delete this?
  Object-Oriented Suicide or delete this;   

我正在通过阅读非常好的C ++ Primer来学习C ++,并且我正在学习C ++如何通过delete关键字解除内存,就像C与free一样。 Java和Pascal没有这种用于释放内存的机制。如果它们运行很长时间并且变量被破坏了,那么它可能会导致程序出错,因此它不应该被轻视。

简而言之,我想知道在C ++中,变量是this.delete()还是删除本身是合法的还是可行的。我们大多听说过在C和C ++中释放指针,这是通过新的freedelete关键字完成的。 Pascal也有指针,但Java没有。所以在Java中它不应该是可能的,因为你没有显式删除对象,C没有对象,所以struct无法free分配的内存,即使从技术上可能,因为C没有对象,Pascal也没有。

所以我认为离开C ++是为了我的问题是否一个对象用this.delete()之类的东西删除自己是合法的吗?

6 个答案:

答案 0 :(得分:6)

对象完全可以执行delete this;

但是,执行此操作后,使用this是一种未定义的行为。

所以,如果你非常小心,事后做了,那么通过delete this;

对一个对象“自杀”是好的和合法的

但是,这真的不是一个好主意,特别是因为它意味着你的类只应由新的实例化,因为te栈上的分配可能导致析构函数被调用两次:删除它,并在离开上下文时。

以下示例说明了为什么这不是一个好主意:

class A
{
public:
    ~A() { std::cout << "Destructor"; }
    void foo() { delete this; } 
};

int main()
{
    {
        A a;
        a.foo(); // OK, a is deleted
    } // Going out of context, the destructor is called again => undefined behavior
    return 0;
}

答案 1 :(得分:5)

this 指针。正确的语法是

 delete this;

是的,这是可能的,但它会使您的对象和指向对象的指针无法使用。

请参阅this以获得良好的阅读效果。

在实践中,使用这种技术是一种代码味道,除非你完全确定你在做什么。

答案 2 :(得分:3)

  

我的问题是一个对象用this.delete()之类的东西删除自己是否合法?

从技术上讲,对象执行delete this是合法的。但是,有一些非常重要的警告是explained in the FAQ

了解delete this解决了一个非常狭窄的技术问题也很重要。它并没有真正解决有关内存管理和垃圾收集的任何重大问题。值得进一步研究的一个方向是the use of smart pointers in C++

答案 3 :(得分:0)

虽然奇怪的一个用例可以说是用户单击“确定”或其他任何内容的对话框,但此操作会导致对话框自行删除,但这是合法的。

当然this指针不再有效,所以你不应该尝试使用它。

答案 4 :(得分:0)

对象完全可以释放自己的内存。但是,由于显而易见的原因,很少使用它。

最常见的用法是实现引用计数内存管理。当调用者调用release()并且引用计数为零时,将删除该对象。由于这发生在成员变量中,因此它使用this指针来删除实例(与在对象外部调用delete foo的方式相同)。例如:

int release()
{
    OSAtomicDecrement32(&m_refCount);
    if (m_refCount <= 0)
    {
        delete this;
    }
    return m_refCount;
}

(请注意,您提到的语法无效 - delete是关键字,而不是方法,而this是指针。)

但要记住几点需要注意。一旦调用此删除,this指针就不再有效,也不会有任何数据成员。从那时起,只能进行非实例引用(例如,局部变量,静态方法和数据等)。

答案 5 :(得分:0)

对象删除其内存的另一种方法是使用名为Resource Aquisition Is Initialisation RAII

的内容

使用此方法,您不会newdelete该对象。它的析构函数在离开其范围时会自动被调用。

即。您可以在以下函数中使用RAII

void foo()

{

  `Object a;`

  `int i = a.SomeMethod();`

  `// a's destructor automatically gets called when the function is out of scope`

}

Further Reading