Во всяком случае, рекомендую данный материал для всех, кто хоть раз сталкивался с ошибками указателей, исключительными ситуациями и GPF.
Когда вы объявляете переменную некоторого типа класса, как например...
var MyVar: TMyClass; |
....всех вас интересует: что делает в этом случае компилятор и достаточно ли распределено памяти, чтобы хранить указатель на экземпляр данного класса в куче памяти. Знайте же: вы не распределили память для данного класа, вы только что распределили память для указателя. Компилятор всегда инициализирует этот указатель в $FFFFFFFF, а это значит, что распределенный блок памяти пуст. Во всяком случае этого достаточно, чтобы сказать что указатель *не* указывает на верную "позицию" памяти и ваш класс *не* содержит никаких данных.
Delphi распределит и заполнит память за вас, но и вы должны немного потрудиться. Когда вы используете один из классов Delphi или свой собственный, вы должны создать его экземпляр. Что это значит: вы должны распределить память и установить на распределенный блок памяти указатель. В некоторых языках это выглядит безобразно, в Delphi же это выглядит так...
|
MyVar := TMyClass.Create; |
Это действительно просто, поскольку метод конструктора Create класса TMyClass является классовым методом - он работает в классе, а не в отдельном объекте. Когда вы вызываете конструктор, Delphi распределяет память и возвращает значение указателя. Присмотритесь: не похоже ли это на вызов функции? Хорошо, если вы раньше не знали, что возвращалось при вызове, то теперь вы это знаете. Вызов TMyClass.Create возвращает указатель на объект типа TMyClass.
В конце концов то, что вам действительно нужно помнить, это...
procedure Example; var MyObj: TMyClass; // класс, который вы создаетеMyList: TList; // встроенный классbegin MyObj := TMyClass.Create;// теперь MyObj содержит адрес блока памяти, распределенной для экземпляра вашего класса MyList := TList.Create;// Код для работы с MyList .... здесь что-то делаем с объектом .... MyList.Free;// Ресурсы MyList удаляются из кучи MyObj.Free;// тоже самое для MyObj end; |
[000312]