Да, то, что вы видели, является правильным.
Нестатические методы класса, как и методы экземпляра, имеют скрытый параметр Self
. Для методов класса, относящихся к заданию класса . Это как компилятор преобразует ваш метод в этом:
type
TTestClassClass = class of TTestClass;
procedure TTestClass_Test(Self: TTestClassClass);
При вызове методы класса на неклассовый приемнике (т.е. ссылки на объект), компилятор вставляет вызов ClassType
для заполнения этого параметра с время выполнения тип объекта, например:
TTestClass_Test(TestClass.ClassType);
метод ClassType
извлекает адрес VMT объекта, но переменная не относится к какой-либо ВМТ. Ваша переменная является либо нулевым указателем, либо неинициализирована, поэтому попытка разыменовать ее для чтения адреса VMT приводит к нарушению доступа, если вам повезет. (Если вам не повезло, он разыскивает адрес, и адрес оказывается где-то еще в адресном пространстве вашей программы, и результат интерпретируется как указатель VMT, даже если это не так.)
Методы класса вызова в ссылках на классы или действительные ссылки на объекты.
TTestClass.Test;
При вызове его на класс-ссылки «буквальным», как указано выше, компилятор уже знает значение первого параметра и преобразует вызов так:
TTestClass_Test(TTestClass);
«Позор вам»? Может быть. Но, по крайней мере, вы были достаточно скромны, чтобы считать, что это может быть ваша ошибка, а не ошибка компилятора, и спросите людей, которые знают больше, чем вы. Поздравляю за это; это одна из замечаний хорошего инженера. –