Программирование - это просто
Advertisement
Главная arrow Уроки программирования arrow Delphi изнутри arrow Delphi Изнутри. Урок 8. Продолжаем изучать TObject. Функции ClassInfo, GetPropInfo, InstanceSize.
29.05.2024 г.
Главное меню
Главная
Интернет магазин
Программные продукты
Биржевые роботы
Искусственный интеллект
Математика и информатика
1С:Предприятие
Уроки C#
Уроки Delphi
Уроки программирования
Web-программирование
Дизайн и графика
Компьютер для блондинок
Исходники
Статьи
Платный раздел
Рассказы про компьютеры
Хитрости и секреты
Системный подход
Размышления
Наука для чайников
Друзья сайта
Excel-это не сложно
Все о финансах
.
Delphi Изнутри. Урок 8. Продолжаем изучать TObject. Функции ClassInfo, GetPropInfo, InstanceSize. Печать E-mail
Автор megabax   
27.05.2010 г.
New Page 2

Delphi Изнутри. Урок 8. Продолжаем изучать TObject. Функции ClassInfo, GetPropInfo, InstanceSize.

Продолжим изучать TObject. Сегодня мы рассмотрим функцию ClassInfo. вот как она реализована:

class function TObject.ClassInfo: Pointer;
begin
    Result := PPointer(Integer(Self) + vmtTypeInfo)^;
end;

Как видим, метод возвращает содержимое ячейки, расположенной по адресу, смещенному на vmtTypeInfo относительно описания класса. Эта функция возвращает информацию о типе. Где ее можно применить?

Например, проверить, поддерживает ли объект заданное свойство:

function HasProperty(Obj : TObject; Prop : string) : PPropInfo;
begin
   Result := GetPropInfo(Obj.ClassInfo, Prop);
end;

Вот пример работы этой ой функции:

procedure TfrmTest.btnTestClick(Sender: TObject);
var a:TLabel;
begin
   a:=TLabel.Create(nil);
   if HasProperty(a,'Alignment')<>nil then messageDlg('Поддерживает',mtInformation,[mbOk],0);
end;

Он у нас выдаст сообщение "Поддерживает". А вот если мы напишем вот так:

procedure TfrmTest.btnTestClick(Sender: TObject);
var a:TLabel;
begin
   a:=TLabel.Create(nil);
   if HasProperty(a,'FFocusControl')<>nil then messageDlg('Поддерживает',mtInformation,[mbOk],0);
end;

То на экране ничего не увидим. FFocusControl у нас является приватным полем класса TCustomLabel, TLabel его наследует, соответственно, тоже как приватное. Но функция GetPropInfo у нас видит только свойства, объявленные как published.

Рассмотрим еще один метод класса TObject - InstanceSize. Он возвращает размер экземпляра объекта. Для иллюстрации работы класса рассмотрим пример:

TInstanceSizeTest1=class(TObject)
     FField:integer;
end;

TInstanceSizeTest2=class(TObject)
    FField:array [1..10] of double;
end;

procedure TfrmTest.btnSizeInstClick(Sender: TObject);
begin
    messageDlg(IntToStr(TInstanceSizeTest1.InstanceSize),mtInformation,[mbOk],0);
    messageDlg(IntToStr(TInstanceSizeTest2.InstanceSize),mtInformation,[mbOk],0);
end;

Данный пример выдаст два сообщения: 8 и 88 - соответственно, размеры экземпляров первого и второго класса. Как видим, второй объект у нас больше так как у него в качестве поля целый массив, а у первого только число. Стоит заметить, что InstanceSize - это не занимаемая объектом память, а именно размер его экземпляра. Определим, например, такой класса:

TInstanceSizeTest3=class(TObject)
     FField:TInstanceSizeTest2;
end;

Проверим, что же у нас вернет InstanceSize:

procedure TfrmTest.btnSizeInst2Click(Sender: TObject);
begin
   messageDlg(IntToStr(TInstanceSizeTest3.InstanceSize),mtInformation,[mbOk],0);
end;

Ответ 8, хотя, казалось бы, у нас есть поля на класс, размером целых 88 байт. Но, дело в том, что храниться то в классе экземпляре TInstanceSizeTest3 не сам объект класса TInstanceSizeTest2 а только указатель на его. Теперь поняли, в чем разница между InstanceSize и объемом занимаемой памяти?

Скажу более, объекта класса TInstanceSizeTest2 , на которое указывает FField может даже не существовать, а FField быть равным nil.

Ну, и на последок посмотрим, а как же устроена функция InstanceSize:

class function TObject.InstanceSize: Longint;
begin
     Result := PInteger(Integer(Self) + vmtInstanceSize)^;
end;

Как видим, принцип работы аналогичный многим другим функциям TObject - обращение к определенному адресу по его смещению. Кстати, конкретные размеры смещений вы можете посмотреть в модуле System*:

Delphi Изнутри. Урок 8. Продолжаем изучать TObject. Функции ClassInfo, GetPropInfo, InstanceSize.

 


Скриншоты, помеченные знаком * , являются цитатами и иллюстрациями  программного продукта "Delphi", авторское право на который принадлежит "Borland Software Corporation".


Последнее обновление ( 30.05.2013 г. )
 
« След.   Пред. »
 
© 2024 Программирование - это просто
Joomla! - свободное программное обеспечение, распространяемое по лицензии GNU/GPL.
Русская локализация © 2005-2008 Joom.Ru - Русский Дом Joomla!
Design by Mamboteam.com | Powered by Mambobanner.de
Я принимаю Яндекс.Деньги