对象是否可以释放其内存

Could an object deallocate its memory?

本文关键字:内存 释放 是否 对象      更新时间:2023-10-16

可能的重复项:
C++:删除这个?
面向对象的自杀或删除此内容;

我通过阅读非常好的书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() 的东西删除自己是否合法?

对象完全

有可能执行delete this;

但是,这样做

之后,使用 this 是一种未定义的行为。

所以,如果你非常小心之后完成,那么一个对象通过做delete this;"自杀"是可以和合法的

但是,这真的不是一个好主意,特别是因为这意味着你的类应该只由 new 实例化,因为堆栈上的分配可能会导致析构函数被调用两次:通过删除这个,以及当脱离上下文时。

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

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

this是一个指针。正确的语法是

 delete this;

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

看这个好好读。

实际上,使用这种技术是一种代码异味,除非你绝对确定自己在做什么。

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

从技术上讲,对象执行delete this是合法的。但是,常见问题解答中解释了许多非常重要的注意事项。

同样重要的是要了解delete this解决了一个非常狭窄的技术问题。它并没有真正解决有关内存管理和垃圾回收的任何大问题。值得进一步研究的一个方向是在C++中使用智能指针。

虽然奇怪的

一个用例是用户单击"确定"或任何内容的对话框,此操作会导致对话框自行删除,但这是合法的。

当然,this指针不再有效,因此您不应尝试使用它。

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

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

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

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

不过,有几个注意事项需要牢记。 调用此删除操作后,this指针将不再有效,任何数据成员也不再有效。 从那时起,只能进行非实例引用(例如,对局部变量、静态方法和数据等)。

对象删除其内存的另一种方法是使用称为"资源获取是初始化"RAII

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

即,您将在以下函数中使用RAII

void foo()

{

  `Object a;`
  `int i = a.SomeMethod();`
  `// a's destructor automatically gets called when the function is out of scope`

}

延伸阅读