Пример использования указателя на класс:

tMyObj=

class

...

end;

tMyObjRef=class of tMyObj;

tChildObj=

class(tMyObj)

...

end; {/class}

var

aMyObjRef:tMyObjRef;

aMyObj:tMyObj;

aChildObj:tChildObj;

После такого объявления можно проводить присваивания такого рода:

if...

then

aMyObjRef:=tMyObj; {при выполнении условия aMyObjRef

стало типом tMyObj}

else

aMyObjRef:=tChildObj; {иначе - типом tChildObj}

aMyObj:=aMyObjRef. Create; {создали объект, тип которого

определяется aMyObjRef}

Без указателей на класс пришлось бы писать вызовы конструктора Create внутри оператора if по отдельности для tMyObj и tChildObj.

Указатели на класс удобно использовать совместно с булевским оператором is, возвращающим true в случае совместимости по присваиванию объекта, указанного перед is, с экземпляром класса, упомянутого после is:

if aMyObj is tAnyObj then...;

Например, если aMyObj – кнопка типа tBatton, а в качестве tAnyObj написано tWinControl, оператор is возвратит true. Если же aMyObj – метка типа tLabel, он возвратит false, так как tLabel является потомком tControl, но не tWinControl.

Существует также специальный вариант приведения типов для объектов при помощи оператора as:

aObj1:=aObj2 as tObj1; {aObj2 вызывается в точности как экземпляр его

класса-прародителя tObj1}

aMyVar:=(aMyObj as tMyRecordObj).Data; {тут Data - свойство;

если это обычное поле, приведение не имеет смысла}

Понятно, что такое приведение возможно только к типу класса-прародителя.

Этот тип приведения очень часто используется в обработчиках событий. Например, если мы хотим изменить координату “x” элемента типа tImage, перетаскиваемого “мышью”, то в обработчике onDragOver элемента, над которым мы его перетаскиваем, надо написать

НЕ нашли? Не то? Что вы ищете?

If Sender is tImage then( Sander as tImage).x=x;

При этом написать Sender. x=x нельзя, так как типом Sender является tObject, а в нем поле x не определено.

4.17. Дополнительные возможности Object Pascal.

4.17.4. Функции

а) могут возвращать значения определенных пользователем типов, включая сложные;

б) внутри каждой функции предопределена доступная по чтению и записи локальная переменная Result, имеющая тот же тип, что и функция. Ее значение до первого присваивания не определено. После завершения процедуры-функции эта функция возвращает значение, присвоенное переменной Result. Использование переменной Result является более наглядным и современным, чем обычный синтаксис языка PASCAL для функций, где значение возвращается через доступную только по записи локальную переменную с именем, совпадающим с именем функции.

4.17.5. Оператор CASE.

Значения вариантов (в том числе диапазоны) не могут пересекаться. Расположение вариантов в порядке возрастания позволяет компилятору оптимизировать код.

4.17.6. Открытые массивы.

Открытым массивом называется массив, используемый как формальный параметр процедуры, длина которого задается не в месте задания процедуры, а при ее вызове. При этом при ее вызове могут использоваться массивы разной длины.

Замечание: если нужен массив переменной длины, для этих целей используют список (мы уже знаем, как это делать). Правда, работа с массивом требует меньше памяти и идет быстрее, чем со списком. В Delphi начиная с версии 2.0 одномерные открытые массивы можно использовать без описания соответствующего типа. С версии 4.0 поддерживаются двумерные открытые массивы. Имеются предопределенные функции Low и High, в качестве параметра которых подставляется имя массива. При этом Low возвращает номер первого элемента, а High — последнего. Надо отметить, что в Delphi (как и в С++, JavaScript и Java) все номера начинаются с 0, а не с 1.

Пример:

program ArcDemo; {MyData - открытый массив}

function Mean(MyData:array of Real):Real;

var i:Integer;

begin

Result:=0;

for i:=Low(MyData)to High(MyData)do {цикл от первого до

последнего элемента}

Result:=Result+MyData[i];

Result:=Result/(High(MyData)-Low(MyData)+1);

end;

var X:Real;

begin

X:=mean([1,9,9,7]); {задаем массив путем перечисления элементов}

end.

Имеется возможность передавать в процедуру открытый массив разнотипных переменных. Такой параметр должен быть описан как array of const. Он может передаваться как по имени (т. е. по указателю на массив), так и по значению (т. е. делается его копия). Внутри процедуры элементы массива рассматриваются как записи типа TVarRec, описанные в модуле System, причем имеется поле типа VType, позволяющее идентифицировать тип фактического параметра.

Пример функции, возвращающей строковое значение переменного числа параметров, а заодно и демонстрирующей не слишком последовательную методику преобразования выражений разных типов в строку:

function AllToStr(const MyParameters:array of const):string;

const

BString:array[Boolean] of string=('False','True');

var

i:Integer;

S:String;

begin

Result:='';

for i:=Low(MyParameters)to High(MyParameters)do

with TVarRec(MyParameters[i])do

begin

case VType of

vtInteger: s:=IntToStr(VInteger);

vtBoolean: s:=Bstring(Vboolean);

vtChar: s:=VChar;

vtEXtended: s:=FloatToStr(VExtended^);

vtString: s:=vString^;

vtPointer: s:=IntToHex(Longint(VPointer),8);

vtPChar: s:=StrPas(VPChar);

vtObject: s:=vObject. ClassName;

vtClass: s:=vClass. ClassName;

end{/case};

Result:=Result+s;

end; {/with...do}

end{/AllToStr};

При вызове

AllToStr([1,'+2','=3,',1e6,'>',1.5e-10,'is',1e6>1.5e-10,'.'])

возвратит строковое значение

1+2=3,1E6>1.5E-10 is true.

4.17.7. Переменные типа variant.

Иногда удобно писать процедуры общего назначения, которые должны выглядеть одинаково для параметров с переменными разного типа. В этом случае целесообразно вместо нескольких процедур использовать одну с параметрами типа variant.

Для переменных типа variant действуют особые правила присваивания: переменной

aMyVar:Variant;

можно присваивать выражения любых типов независимо от текущего значения переменной:

begin

...

aMyVar:=1;

...

aMyVar:=true;

...

aMyVar:='SomeString';

...

end;

При присваивании строковой переменной (или участии в строковом выражении) переменная вариантного типа возвращает строку с соответствующим значением. В предыдущем примере это было бы '1','true' и 'SomeString', соответственно.

Приведение типов для других случаев описывать не будем. Информацию по этому вопросу можно найти в специальной документации среды Delphi.

Работа с переменными типа variant гораздо медленнее чем для обычных, т. к. проверки и приведения типов во время исполнения программы занимают много времени. Кроме того, жесткость диагностики для этого случая значительно снижена, что может привести к возникновению не отслеживаемых компилятором ошибок. Поэтому, по мере возможностей, лучше избегать применения переменных variant. Их целесообразно использовать только в случае вызова DLL (Dynamic Link Libraries), написанных на языке С, для обеспечения совместимости по типу с параметрами функции из этих библиотек.

5. Визуальное проектирование в среде Delphi.

Перед началом работы обычно надо настроить пути к библиотеке Delphi, а в Delphi 3.0 также установить пакеты. Это связано с тем, что Windows 95 (и, тем более, NT 4.0) имеет индивидуальные настройки для каждого пользователя. При установке Delphi все настройки выполняются автоматически, но только для Desktop того пользователя, который производил установку пакета. Помимо упомянутых настроек рекомендуется указать пути для директорий, в которых будут создаваться выходные и вспомогательные файлы.

5.8. Создание экранных форм. Инспектор объектов.

При входе в Delphi автоматически открывается проект "по умолчанию". Изначально это проект с пустой экранной формой, на которой пунктиром показана сетка, к которой идет привязка для выравнивания размеров и положений компонентов на форме. Для того, чтобы создать на форме новый компонент, надо "мышью" щелкнуть на соответствующем компоненте из палитры компонентов, а затем щелкнуть "мышью" на том месте экранной формы, где необходимо расположить компонент. Перетаскивание по форме компонента осуществляется либо "мышью" по технологии "хватай и тащи" (drag and drop), либо с помощью инспектора объектов путем задания значений свойств top и left (расстояний от верхнего и левого краев формы). Если во время проектирования вы случайно закрыли форму (нажали на "крестик" в правом верхнем углу формы), следует открыть project manager в опции view в меню Delphi. Менеджер покажет имена всех форм и модулей, имеющихся в проекте. Двойной щелчок на имени приведет к "всплыванию" наверх соответствующей формы или модуля.

5.9. Палитра компонентов.

Мы будем описывать только наиболее важные свойства и события для компонентов и перечислим только наиболее часто используемые компоненты из стандартных библиотек Delphi 3.0. Для Delphi 2.0 практически все далее сказанное также справедливо. Существенным отличием является более развитая справочная система в Delphi 3.0, позволяющая в режиме on-line получать практически всю необходимую информацию, что резко облегчает работу. Поэтому приводимые далее описания компонентов дают лишь общее знакомство с палитрой.

5.9.4. Метка (tLabel).

Этот компонент предназначен для показа в некотором месте формы статического или изменяющегося в процессе работы приложения текста. Свойство font позволяет выбирать тип, стиль, размер и цвет фонта, а height и width — задавать размеры отведенного под метку места. Свойство caption ("титр", "подпись под картинкой") позволяет вводить в инспекторе объектов (object inspector) или присваивать программно в процессе работы строку с текстом длинной до 255 символов. Свойство WordWrap дает возможность автопереноса текста на следующую строку при превышении шириной строки значения Width. Свойство AutoSize, напротив, вызывает автоматическое установление значения Width по длине строки.

Метка не может захватывать фокус, поэтому на нее невозможно установить курсор. В результате кусок текста на экране, созданный с помощью tLabel, невозможно выделить и скопировать в буфер обмена (clipboard), что бывает крайне неприятно для пользователей программ. Поэтому вместо tLabel рекомендуется использовать компонент tEdit в режиме запрета редактирования текста и с цветом, совпадающим с цветом формы.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16