5

我想通过自己的方法销毁类实例。例如:

obj = Object()
obj:destroy()
type(obj) == nil

对象是在C上实现的。有可能吗?

如果不可能,第二种方法是:

_G["obj"] = nil
collectgarbage()

谢谢!

4

3 回答 3

5

我想通过自己的方法销毁类实例。

您应该不惜一切代价避免这种情况仅在绝对需要时才在 Lua 中公开显式析构函数。

处理这个问题的正确方法是给你的 Lua C 对象一个带有metamethod__gc元表。这个元方法将在 Lua 垃圾收集对象之前被调用。

如果您绝对必须使用显式析构函数(因为您希望用户能够在完成后立即释放昂贵的资源,而无需等待垃圾回收),那么您需要做两件事:

  1. 要求用户显式销毁对象。也就是说,对象应该能够通过析构函数或垃圾回收来销毁。

  2. 当对象被显式销毁时不要破坏它。如果用户调用显式销毁函数,则每个接受此对象的函数(成员函数或自由函数)都需要继续工作。这些功能可能什么都不做,这很好。但程序不应该崩溃

    基本上,您的对象在被明确销毁时仍需要处于“活动”状态。您需要让对象成为僵尸:活着,但不是很有用。这样,即使您的程序没有做正确的事情,您的程序仍然可以运行。

于 2012-07-06T16:04:15.487 回答
3

在您的示例中简单obj = nil就足够了。请注意,您不会破坏对象的内容,而是删除了变量中的引用obj,从而使内存中某处的真实对象减少了一个引用,并且如果达到 0 个引用,则取消引用一个符合 GC 的条件。

如果您的对象在销毁时没有要执行的外部任务,那么这几乎就是您所需要的。只是通过让它们超出范围或用其他东西或覆盖包含这些引用的变量/表成员来丢失所有引用nil。否则,您需要先调用特定于对象的析构函数,然后才能删除引用。

不可能让这样的析构函数自动从各处删除所有引用,但至少它可以清除对象的内部状态并设置一些内部标志,表明对象不再可用或准备重新初始化。

于 2012-07-06T12:35:45.553 回答
1

在某种程度上,这是可能的。您可以在对象中创建一个子表作为私有数据存储。该子表仅由对象管理,因此只能有一个引用。如果您为对象定义析构方法,那么它将删除相应的子表,使其符合垃圾回收条件。当然,父表仍然存在,只留下不占用大量资源的方法。

这是否是“好的设计”是主观的。我只是为提出的问题提供一个解决方案。

于 2018-01-14T15:47:51.680 回答