我试图在AHK中绕开我的头。我是C++开发人员,所以想使用 RAII(__New
,__Delete
),但看起来我错过了一些概念,因为对我来说事情看起来非常违反直觉。
经过一些尝试,我想出了这个简单的例子:
class Scenario
{
__New()
{
MsgBox, NEW
}
__Delete()
{
MsgBox, DELETE
}
}
scenario := new Scenario
scenario := new Scenario
scenario := 1
scenario := {}
scenario := new Scenario
Return
结果,我收到以下消息:
- 新增功能
- 新增功能
- 删除
- 删除
问题:
- 为什么对象在第二次分配期间没有被销毁?我假设引用的数量会变成 0,不是吗?
- 为什么我连续获得 2 次破坏?同时,该对象存储在哪里?
scenario
变量如何同时保存两个引用? - 为什么不叫第三个建筑?
- 为什么对象在第二次作业期间没有被销毁?
尚未触发垃圾回收
我假设引用的数量会变成 0,不是吗?
引用变为 0 不一定会触发 GC
- 为什么我连续得到 2 次破坏?
垃圾回收同时清理了两个引用
同时,该对象存储在哪里?
堆
场景变量如何同时容纳这两个引用?
scenario
不同时保存这两个引用
- 为什么不叫第三个构造?
仅构造两个方案对象。变量scenario
是一个动态变量,并不总是类Scenario
的实例。 最后一个赋值scenario := {}
只是创建一个空对象。
好的,找出缺少的内容。两件事:
- AHK 脚本不区分大小写。
- 由于
class
本身就是 AHK 中的对象,因此可以用另一个对象覆盖该类。
以下是文档的一部分:
由于类是通过变量引用的,因此类名不能用于在同一上下文中引用类和创建单独的变量(例如保存类的实例)。例如,
box := new Box
会将 Box 中的类对象替换为自身的实例。[v1.1.27+]:#Warn ClassOverwrite
允许在加载时为每次尝试覆盖类时显示警告。
这解释了上面的代码中发生的事情:变量名scenario
实际上与类名Scenario
相同,所以我只是悄悄地用一个空对象覆盖了我的类。
此外,由于类的新实例是在赋值之前创建的,因此我连续得到两个"NEW",仅比"DELETE"多
。