Програмиране в Delphi 6
Add('2-ро число: '#9+V2);
Екранният изглед на работещата програма е показан на фиг. 10.1. Както можете да видите, новият вариант лесно се справя с поддръжката на комплексни числа: функцията VarComplexCreate създава вариант, съдържащ комплексно число, а по-нататъшното поведение на варианта е стандартно (поддържа математически операции и преобразуване в тип низ). Тази лекота обаче е измамна: изходният текст на модула VarCmplx, който всъщност дава на варианта допълнителни свойства (по подразбиране се намира във файла Source\Rtl\Common\VarCmplx.pas), съдържа повече от 30 000 байта.
Нас. 229 показва структурата на записа TVarData. Първите два байта в този запис (полето VType) съхраняват флага за стойност на варианта, останалите 14 байта могат да се използват за съхраняване на данни.
Ориз. 10.1. Демонстрация на сложни опции
Създаването на индивидуален вариант става на три етапа.
В резултат на тези стъпки получавате пълноценна версия, обогатена с нови свойства: тя може да съхранява не само тези стойности, които са изброени в таблицата. 10.2, но и всички други, включително свойства и методи! (В този последен случай изпълнимият клас на новия вариант наследява TInvokeableVariantType или TPublishableVariantType вместо TCustomVariantType.)
10.5.1. Поставяне във варианта на новите стойности
За да поставите нова стойност (неосигурена от стандартния вариант) във вариант, трябва да създадете подходящ клас и да поставите обект от този клас в съответното поле rvarData. Ето как например се поставят сложни данни в модула VarCmplx:
TComplexVarData = опакован запис
Запазено1, Запазено2, Запазено3: Word;
Такъв запис запазва само 16-байтовата структура TVarData, поставяйки се в полето VComplexпрепратка към обект от класа TComplexData. Всъщност комплексните числа се съхраняват в полетата на доста сложен клас:
TComplexData = class(TPersistent) private
FReal, Fimaginary: двойно;
Този клас предоставя множество методи, които управляват новите данни. И така, просто извикване на VarComplexCreate
задейства няколко метода, които създават VComplex обект и попълват неговите полета:
процедура VarComplexCreateInto (var ADest: Variant;
const AComplex: TComplexData);
край; функция VarComplexCreate(const AReal, AImaginary: Double):
(CM. файл Source\Rtl\Common\VarCmplx.pas).
10.5.2. Създаване на наследник на TCustomVariantType
Тип TCustomVariantType или неговите най-близки производни TPublishableVariantType и TInvokeableVariantType Съдържат методи и
свойства, които в точното време извикват методите и свойствата на обекта VC omplex за извършване на определени трансформации. Следният клас е деклариран в модула varcmpix:
class(TPublishableVariantType, IVarStreamable) защитен
функция LeftPromotion(const V: TVarData;
const Оператор: TVarOp;
out RequiredVarType: TVarType): Boolean; отмяна;
функция RightPromotion(const V: TVarData;
const Оператор: TVarOp;
out RequiredVarType: TVarType): Boolean; отмяна;
функция GetInstance(const V: TVarData): TObject; отмяна;
процедура Clear(var V: TVarData);
функция IsClear(const V: TVarData): Boolean; отмяна;
процедура Copy(var Dest: TVarData;
const Източник: TVarData;
const Indirect: Boolean);
процедура Cast(var Dest:
const Източник: TVarData);
процедура CastTo(var Dest: TVarData;
const Източник: TVarData;
констAVarType: TVarType);
процедура BinaryOp(var Left: TVarData;
const Вдясно: TVarData;
const Оператор: TVarOp); отмяна;
процедура UnaryOp(var Right: TVarData;
const Оператор: TVarOp);
функция CompareOp(const Left: TVarData;
const Вдясно: TVarData;
const Оператор: Цяло число): Boolean;
процедура Streamin(var Dest: TVarData;
const Поток: TStream);
процедура StreamOut(const Източник: TVarData;
const Поток: TStream);
Имайте предвид, че класът TComplexVariantType е интерфейсен клас (вижте раздел 9.4.1). В допълнение към методите, общи за варианта, той също така прилага два метода, специфични за интерфейса на Ivarstreamabie, Streamin и StreamOut, с които стойностите на новия интерфейс се съхраняват и четат от потока.
Задачата на този клас е да дава унифицирани команди, които могат да бъдат интерпретирани от обекта vcomplex като команди за преобразуване на типа съхранени данни, сравняването им, прилагането на определени операции върху тях и накрая записването им в поток и четенето им от него. Например, методът cast на този клас се извиква, за да преобразува други типове стойности в сложен тип, методът castTo се извиква, за да го преобразува обратно, методът BinaryOp имплементира двоична операция, а Unarydp имплементира унарна и т.н.
Още веднъж подчертавам, че основната работа (например за извършване на двоични операции) се изпълнява от методите на класа TComplex-Data. Класът TCompiexVariantType замества абстрактните методи на своя родител, свързвайки TComplexData за решаване на определен проблем.
Тъй като е необходим готов екземпляр (обект) на класа TCompiexVariantType за създаване на екземпляр на нов вариант, той се създава в секцията за инициализация на модула varcmpix и се унищожава в последната секция:
10.5.3. Създаванепомощни методи
Въпреки интензивното използване на класовете TCompiexData и TCompiexVariantType, тези класове в крайна сметка остават скрити за потребителя на новия вариант поради набор от спомагателни
методи като VarComplexCreate, VarIsComplex, VarAsComplex и др.
които трансформират извиквания на обикновени процедури в извиквания на методи и достъп до свойства на съответните класове.