5

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

我正在通过阅读非常好的书 C++ Primer 来学习 C++,并且我正在学习 C++ 如何通过delete关键字来释放内存,就像 C 对free. Java 和 Pascal 没有这种显式释放内存的机制。如果程序运行很长时间并且需要的变量被破坏,则可能会导致程序错误,因此不应轻视。

简而言之,我想知道例如在 C++ 中让变量执行this.delete()和删除自身是否合法或可取。我们大多听说过在 C 和 C++ 中释放指针,这是通过 newfreedelete关键字完成的。Pascal 也有指针,但 Java 没有。所以在Java中它不应该是不可能的,因为你没有明确地删除对象,C没有对象,所以即使技术上可行,它struct也不能free分配内存,因为C没有对象,Pascal也没有。

所以我想这让 C++ 成为我的问题,一个对象用类似的东西删除自己是否合法this.delete()

4

6 回答 6

6

一个对象完全有可能做delete this;.

但是,这样做之后, usingthis是一种未定义的行为。

所以,如果你非常小心地在之后做,那么一个对象通过做“自杀”是可以的并且是合法的delete this;

但是,这确实不是一个好主意,尤其是因为这意味着您的类只能由 new 实例化,因为在 te 堆栈上的分配可能会导致析构函数被调用两次:通过 delete this 和脱离上下文时。

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

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;
}
于 2012-05-28T10:58:31.803 回答
5

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

 delete this;

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

请参阅内容以供阅读。

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

于 2012-05-28T10:58:19.743 回答
3

我的问题是对象使用 this.delete() 之类的方法删除自己是否合法?

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

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

于 2012-05-28T10:59:05.517 回答
0

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

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

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

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

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

于 2012-05-28T11:05:13.190 回答
0

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

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

于 2012-05-28T10:59:45.313 回答
0

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

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

即您将RAII在如下函数中使用:

void foo()

{

  `Object a;`

  `int i = a.SomeMethod();`

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

}

延伸阅读

于 2012-05-28T11:11:09.163 回答