Не может создать класс в AHK после уничтожения
Я пытаюсь обернуть голову вокруг занятий в AHK. Я C++ dev, поэтому хотел бы использовать RAII (__New
, __Delete
), но, похоже, я скучаю по некоторым понятиям, поскольку для меня все выглядит очень нелогичным.
После нескольких попыток я придумал этот простой пример:
class Scenario
{
__New()
{
MsgBox, NEW
}
__Delete()
{
MsgBox, DELETE
}
}
scenario := new Scenario
scenario := new Scenario
scenario := 1
scenario := {}
scenario := new Scenario
Return
В результате я получаю следующие сообщения:
- NEW
- NEW
- УДАЛЯТЬ
- УДАЛЯТЬ
Вопросы:
- Почему объект не разрушается во время второго задания? Я бы предположил, что количество рефсов будет равно 0, нет?
- Почему я получаю 2 разрушения подряд? Где этот объект хранился тем временем? Как мог
scenario
переменная содержит обе ссылки? - Почему не была названа третья конструкция?
2 ответа
- Почему объект не разрушается во время второго задания?
Сборка мусора еще не началась
Я бы предположил, что количество рефсов будет равно 0, нет?
Ссылка на 0 не обязательно вызывает GC
- Почему я получаю 2 разрушения подряд?
Сборка мусора убрала обе ссылки одновременно
Где этот объект хранился тем временем?
Куча
Как переменная сценария может содержать обе ссылки?
scenario
не содержит обе ссылки
- Почему не была названа третья конструкция?
Только два объекта Сценария построены. Переменная scenario
является динамической переменной и не всегда является экземпляром класса Scenario
, Последнее назначение scenario := {}
просто создает пустой объект.
Хорошо, выяснил, чего не хватало. Две вещи:
- AHK скрипт не учитывает регистр.
- поскольку
class
это отдельный объект в AHK, можно переопределить класс другим объектом.
Вот часть документации:
Поскольку на класс ссылаются через переменную, имя класса нельзя использовать как для ссылки на класс, так и для создания отдельной переменной (например, для хранения экземпляра класса) в том же контексте. Например,
box := new Box
заменит объект класса в Box экземпляром самого себя. [V1.1.27+]:#Warn ClassOverwrite
позволяет отображать предупреждение во время загрузки для каждой попытки перезаписать класс.
Это объясняет, что произошло в коде выше: имя переменной scenario
фактически совпадает с именем класса Scenario
так что я просто тихо перекрыл свой класс пустым объектом.
Кроме того, поскольку новый экземпляр класса создается перед присваиванием, я получил два 'NEW' подряд, но не 'DELETE'.