Работа с классами в Kylix
Понятие исключения
Обработка исключительных ситуаций
Защита ресурсов и регенерация исключений
Генерация исключений
Данная глава расскажет вам, как использовать классы в среде Kylix. Кроме того,
вы узнаете, что такое исключительная ситуация и как можно самостоятельно обрабатывать
исключительные ситуации. Вы научитесь создавать обработчики исключений, а также
генерировать собственные исключения.
Работа с классами в Kylix
Напомним основные положения о классах, которые были достаточно подробно рассмотрены
в пятой главе книги.
Класс - это абстрактное определение, инкапсулирующее понятия: свойства, методы,
события и члены класса (например, локальные переменные, объявленные внутри класса).
Когда вы создаете экземпляр класса - он называется объектом. Термин "объект"
часто в документации по Kylix используется более свободно, и, где различие между
объектом и классом, не важно. Этот термин может обозначать класс, от которого
данный объект произошел.
Часто программисту приходится создавать собственные классы для решения каких-либо
задач, не предусмотренных стандартными классами CLX Kylix. Класс, который вы
создаете, может иметь в качестве предка основной класс TObject или его потомок.
Объявление нового класса содержит три допустимые секции, обеспечивающие доступ
к полям и методам класса:
Туре
TClassName = Class(TObject)
public
{public fields}
{public methods}
protected
{protected fields}
{protected methods}
private
{private fields}
{private methods}
end;
Kylix позволяет вам объявлять самостоятельно нужные классы для использования
их в своих приложениях. Некоторые версии Kylix включают в себя специальные возможности,
которые называются завершение класса. Данные возможности позволяют упростить
работу программиста по созданию нового класса. Упрощение происходит благодаря
автоматическому генерированию скелета кода для членов класса, который вы определяете.
Ниже перечислены шаги, позволяющие вам объявить новый класс.
В интегрированной среде разработчика Kylix начните новый проект и выполните
команду меню Kylix File/New Unit (Файл/Новый модуль). Таким образом вы создадите
новый модуль проекта, в котором будет объявлен новый класс.
Добавьте в секцию интерфейса нового модуля (interface) секцию uses и type.
В секции type напишите объявление нового класса. Здесь вам необходимо объявить
все внутренние переменные класса, свойства, методы и события класса.
Например,
TMyClass = class; {Новый класс является потомком класса TObject}
public
...
private
...
published(Класс является потомком TPersistent или его потомков}
...
Примечание
Вы должны включить в описание класса секцию published только в том случае, если
ваш класс является потомком класса TPersistent или его потомков.
Если вы хотите создать свой класс как потомка определенного класса, то вам необходимо
указать это в объявлении класса:
TMyClass = class(TParentClass); {Новый класс является потомком класса TParentClass}
Например,
type TMyButton = class(TButton)
property Size: Integer;
procedure DoSomething;
end;
В этом примере мы определяем класс TMyButton, который является потомком класса
TButton и будет иметь все свойства, события и методы своего родителя, а также
дополнительное свойство size целого типа и процедуру DoSomething.
Если ваша версия Kylix включает завершение класса, выполните следующие действия:
поместите курсор внутри определения методов класса в секции интерфейса (interface)
и нажмите комбинацию клавиш <Ctrl>+ +<Shift>+<C> или щелкните
правой кнопкой мыши и в выпадающем меню выберите пункт Complete Class at Cursor
(Завершить класс в пределах курсора). Kylix завершит объявление каждого незавершенного
свойства и создаст необходимые пустые методы в секции реализации (implementation).
Если же ваша версия Kylix не поддерживает завершение классов, вам придется делать
все самостоятельно.
В приведенном ниже примере, если у вас есть завершение класса, Kylix добавит
слова read и write, включая все поддерживаемые поля и методы:
type TMyButton = class(TButton}
property Size: Integer read FSize write SetSize;
procedure DoSomething;
private
FSize: Integer;
procedure SetSize(const Value: Integer);
Он также добавит следующий код в секцию реализации модуля:
{ TMyButton }
procedure TMyButton.DoSomething;
begin
end;
procedure TMyButton.SetSize(const Value: Integer);
begin
FSize := Value;
end;
Теперь заполните методы. Для примера, если вы хотите, чтобы кнопка издавала
звуковой сигнал каждый раз при вызове метода DoSomething, добавьте команду Веер
между словами begin и end данного метода в разделе реализации:
{ TMyButton }
procedure TMyButton.DoSomething;
begin
Beep;
end;
procedure TMyButton.SetSize(const Value: Integer);
begin
FSize := Value;
DoSomething;
snd;
Примечание
Наша кнопка будет также издавать звуковой сигнал в случае, если вы вызовете
метод SetSize для изменения ее размера.
Понятие исключения
Среда Kylix предназначена для быстрой разработки довольно сложных про-раммных
комплексов. Сложная программа может по-разному взаимодействовать с операционной
системой и уже запущенными в ней приложениями. Кроме того, пользователи вносят
частичку непредсказуемости при работе с рограммой. В результате любое из вышеописанных
взаимодействий может е выполниться или завершиться неправильно. Такие ситуации
мы и будем ассматривать далее в этой главе. Ошибочных ситуаций, которые могут
возникнуть, достаточно много. Простейшим примером может являться попытка рограммы
выполнить деление на ноль или открытие несуществующего файла на диске. Все возможные
ошибки программист предугадать не может, для облегчения труда разработчика программ
Kylix включает поддержку так называемых исключений или исключительных ситуаций.
Исключительная ситуация - это непредвиденное событие, произошедшее при выполнении
программы и способное повлиять на ее дальнейшее выполнение.
Kylix предоставляет программисту механизм обработки исключительных ситуаций.
Обработчик исключений позволяет приложению корректно обработать возникшую исключительную
ситуацию (ошибку) и продолжить выполнение программы без потери данных и ресурсов.
Для создания таких безопасных программ нужно лишь научиться писать обработчики
исключительных ситуаций.
Далее мы рассмотрим задачи, которые можно решать с помощью исключений.
Обработка исключительных ситуаций
Чтобы сделать свое приложение устойчивым к ошибкам, вам необходимо опознать
исключение и обработать его. Если вы не напишете обработчик исключения, приложение
отобразит окно сообщения об ошибке.
Обработчик исключения - это программа, которая начинает свое выполне-е в случае
возникновения определенной исключительной ситуации. Обработчик исключения выполняется
вместо стандартной реакции приложения на ошибку.
При обработке исключительных ситуаций Kylix работает с такк называемыми объектами
исключений. Так как Kylix - объектно-ориентироованная среда программирования,
то логично, что и исключительная ситуация - тоже объект. Для работы с этим объектом
в Kylix присутствуют специальные языковые конструкции, которые мы и рассмотрим
далее.
Программисту чаще всего известно, в каком именно месте гпрограммы может возникнуть
исключительная ситуация (например, место, пгде происходит открытие файла, расположенного
на диске). Для того чтобы обработать ее, нужно этот кусок кода защитить. Таким
образом, данный бллок кода будет называться защищенным.
Рассмотрим языковые конструкции, предоставляемые средой Kylix, которые обеспечивают
защищенный код.
Первая конструкция имеет вид, представленный в листинге 9. 1.
Листинг 9.1. Синтаксис конструкции try ... except
try
// здесь находятся операторы защищенного кода
except
on Exceptionl do // операторы, выполняемые в случае
// возникновения ошибки 1
on Exception2 do // операторы, выполняемые в случае
// возникновения ошибки 2
...
else
// операторы, выполняемые в случае возникновения ошибки, не являющейся ни ошибкой
1
//ни ошибкой 2
end;
Таким образом, вы размещаете "опасный" участок кода после слова try,
и если при выполнении этого кода произойдет исключительная ситуация, оно прекратится
и начнут выполняться команды, расположенные после слова except.
В разделе except могут находиться или только операторы обработки исключений,
которые начинаются со слова-приставки on, или только произвольные операторы,
не являющиеся операторами обработки исключений. В вышеприведенном листинге представлена
ситуация, когда в разделе except находятся только операторы обработки исключений.
Если в блоке операторов, расположенных после слова try, произошла ошибка Exception1,
то будут выполнены только те команды, которые расположены после слов on Exception1
do. Далее объект исключения уничтожается и программа продолжает выполнять операторы,
расположенные после слова end; рассматриваемой конструкции.
Раздел после слова else является необязательным и может отсутствовать. Он предназначен
для обработки любых других исключений, не предусмотренных в разделе except.
Если же раздел else отсутствует, но в защищенном коде произошла исключительная
ситуация, не предусмотренная ни одним обработчиком исключений on Exception do,
то произойдет стандартная (определенная операционной системой) обработка данной
исключительной ситуации с появлением соответствующего информационного окна с
сообщением об ошибке.
Рассмотрим оператор обработки исключений более подробно. Как видно из листинга
9.1, данный оператор может присутствовать внутри раздела except или принимать
одну из двух форм:
on <класс исключения> do <оператор>;
ИЛИ
on <имя>: <класс исключения>
do // операторы, в которых можно использовать свойства исключения
В листинге 9.1 мы привели только первую форму представления оператора. fio,
так как исключение является объектом, то было бы иногда очень удобнo обратиться
к его свойствам. Однако для того, чтобы обращаться к свойствам какого-либо объекта,
необходимо знать его имя. Вторая форма оператора обработки исключений применяется
именно тогда, когда нам нужно тратиться к свойствам возникшего исключения. Для
этого исключению присваивается временное имя <имя> и к его свойствам можно
обращаться через точку:
<имя> . <свойство>
В листинге 9.2 приведена та же конструкция, что и в листинге 9.1, только в блоке
except нет операторов обработки исключений. Таким образом, при возникновении
любой исключительной ситуации в защищенном блоке будут выполняться операторы,
расположенные после слова except.
Листинг 9.2. Конструкция try ... except без операторов обработки исключений
try
// здесь находятся операторы защищенного кода
except
Operator 1; // операторы, выполняемые в случае
Operator2; // возникновения любой исключительной ситуации,
Operator3; // возникшей в защищенной области
...
end;
Приведем небольшие примеры использования защищенных блоков программы. В листинге
9.3 представлен пример обработки исключительной ситуации деления на ноль.
Листинг 9.3. Обработка деления на ноль
try
а: =8 ;
b:=0;
с:=а/b;
except
on EZeroDivide do MessageBox('Внимание! Деление на ноль!')
end;
При выполнении данного кода будет сгенерирована исключительная ситуация, принадлежащая
к классу EZeroDivide (деление целых чисел на ноль). Данная исключительная ситуация
обработается в секции except и приложение выдаст на экран окно с сообщением
Внимание! Деление на ноль! (рис. 9.1).
Рис. 9.1. Окно сообщения
Примечание
Знание имен классов исключений необходимо при обработке исключительных ситуаций.
Мы рассмотрим их далее в этой главе.
В листинге 9.4 приведен пример использования временного имени объекта исключения
в своих целях.
Листинг 9.4. Использование временного имени объекта исключения
try
ScrollBar1.Max:=ScrollBar.Min-1;
except
on E: EInvalidOperation do
MessageDlg( 'Произошло исключение: '+Е.Message, mtlnformation, [mbOK] ,0)
end;
В защищенном блоке кода программы будет осуществлена недопустимая для объекта
ScrollBox1 операция присвоения максимального значения списка меньшего, чем минимальное
значение. Возникнет исключение класса EInvalidOperation. Таким образом, мы присваиваем
объекту исключения, принадлежащего к классу EinvalidOperation, временное имя
Е, после чего можем обращаться к свойствам объекта исключения Е. Мы самостоятельно
зыводим в окне сообщения текст ошибки Е.Message, который выдается по /молчанию
(в том случае, если бы нашего обработчика исключения не было). Результат работы
кода листинга 9.4. представлен на рис. 9.2.
Рис. 9.2. Окно сообщения об исключении
Примечание
С объектами исключений нужно работать очень осторожно. Ни в коем случае самостоятельно
не уничтожайте объекты исключения - это может привести к ошибке работы программы.
После завершения обработки исключения Kylix самостоятельно позаботится об его
уничтожении.
Рассмотрим теперь классы исключений. Они необходимы для обработки конкретных
исключительных ситуаций. Мы представляем классы исключений не в иерархии, а
в алфавитном порядке.
Exception - базовый класс исключений. Все другие классы исключений являются
прямыми или косвенными потомками данного класса.
EAbort - потомок класса Exception. Данный класс исключения не отображает диалогового
окна ошибки при возникновении исключения. Простейшим способом генерации данного
исключения является вызов метода Abort.
EAbstarctError - потомок класса Exception. Генерируется при попытке вызова абстрактного
метода.
EAccessViolation - потомок класса EExternal. Генерируется при неверной работе
с памятью.
EAssertionFaiied - потомок класса Exception. Класс исключения, генерируемый
в случае ошибки при проверке истинности с помощью процедуры Assert. Данное исключение
возникает, только если включена директива компилятора Kylix $ASSERTION ON.
EBcdException - потомок класса Exception. Базовый класс при работе со значениями
типа BCD (Binary code decimal). Генерируется обычно в случае ошибки при попытке
преобразования типа variant или string в BCD.
EBcdOverfiowException - потомок класса EBcdException. Генерируется при невозможности
преобразования типа variant в BCD с требуемым количеством символов после запятой.
EBitsError - потомок класса Exception. Генерируется при ошибке доступа к массиву
булевых значений.
EClassNotFound - потомок класса EFiierError. Генерируется при невозможности
найти определенный компонент при чтении из потока.
EComponentError - потомок класса Exception. Возникает при ошибке регистрации
или переименования компонента.
EConvertError - потомок класса Exception. Генерируется при ошибке преобразования
строк или объектов.
EDatabaseError - потомок класса Exception. Базовый класс для всех ошибок при
работе с базами данных.
EDateTimeError - потомок класса ECommonCalendarError. Возникает При неправильном
вводе даты или времени пользователем в компонент TdateTimePicker.
EDbcClient - потомок класса EDatabaseError. Генерируется в случае ошибки при
работе с набором данных клиента базы данных.
EDBEditError - потомок класса Exception. Возникает в случае попытки помещения
данных в поле, которые не являются совместимыми с заданной маской поля.
EDivByZero - потомок класса EintError. Возникает при ошибке целочисленного
деления на ноль. При делении на ноль чисел с плавающей запятой возникает другое
исключение EZeroDivide (см. ниже).
EDSWriter - потомок класса Exception. Ошибка при попытке создания пакета данных
из набора данных.
EExternal - потомок класса Exception. Базовый класс для всех ошибок, происходящих
вне приложения во время его выполнения
EExternalException - потомок класса EExternal. Исключение с нераспознаваемым
кодом.
EFCreateError - потомок класса EstreamError. Неудачная попытка создания нового
файла. Например, неправильное имя файла или если файл с таким именем уже существует.
EFilerError - потомок класса EstreamError. Попытка повторной реги-страции класса.
EFOpenError - потомок класса EStreamError. невозможно окрыть требуемый файл.
Файл не найден или не существует заданного пути к файлу.
EHandleComponentException - потомок классаException. Невозможно получить дескриптор
окна.
EHeapException - потомок класса Exception. Класс исключения для ошибок, связанных
с кучами распределения памяти.
EldAcceptWaitCannotBeModifiedWhileServerlsActive - потомок класса EldTCPServerError.
Возникает, когда свойство TIdTCPServer.AcceptWait изменяет свое значение при
активном TCP-сервере.
EldAlreadyConnected - потомок класса EldException. Попытка создать соединение
с компонентом Indy, когда оно уже существует.
EldCanNotChangeTarget - потомок класса EldException. Попытка установки свойства
TidLogDebug. Target в то время, когда свойство
TIdLogDebug.Active ИМССТ Значение true.
EldCanNotCreateMessagePart - потомок класса EldMessageException. Ошибка вызова
конструктора класса TidMessagePart.
EldClosedSocket - потомок класса EldException. Попытка записи в закрытый ТСР-сокет.
EldConnClosedGracefully - потомок класса EldSilentException. Возникает в случае
успешного закрытия соединения.
EldCorruptServicesFile - потомок класса EldException. Поврежденодин из файлов
SERVICES. Данные файлы располагаются на диске в разных местах, в зависимости
от операционной системы:
BSD Unix - /etc/;
Windows 9x, Millenium - папка Windows;
Windows NT - папка Windows/System32.
EldCouldNotBindSocked - потомок класса EldSockedHandleError. Ошибка привязки
дескриптора сокета.
EldDnsResolverError - потомок класса EldException. Ошибка класса TIdDnsResolver.
EldTunnelConnectToMasterFailed - потомок класса EldTunnelException. Данное исключение
генерируется автоматически при ошибке туннельного соединения.
EidException - потомок класса Exception. Базовый класс исключений для Indy-компонентов.
Компоненты Indy не используют стандартные исключения.
EldFailedToRetreiveTimeZonelnfo - потомок класса EidException. Данные о временной
зоне не могут быть получены текущим пользователем системы.
EldFTPFileAlreadyExists - потомок класса EidException. Файл не может быть перезаписан
с помощью запроса FTP Get.
EldHTTPCannotSwitchSessionStateWhenActive - потомок класса EidHTTPServerError.
Невозможно изменить состояние активного HTTP-сервера.
EldHTTPErrorParsingCommand - потомок класса EidHTTPServerError. Неизвестная
HTTP-команда.
EldHTTPHeaderAlreadyWritten - потомок класса EidHTTPServerError. Заголовок
HTTP-документа уже существует.
EldHTTPServerError - потомок класса EidException. Базовый класс для всех HTTP-исключений
в Indy.
EldHTTPUnsopportedAuthorisationScheme - потомок класса EidHTTPServerError. Неподдерживаемый
формат имени пользователя и пароля для идентификации на HTTP-сервере.
EldlcmpException - потомок класса EidException. Исключение для всех ICMP-компонентов.
EldlnterceptPropInvalid - потомок класса EldTCPConnectionError. Попытка использования
возможностей, не поддерживаемых текущим
классом TldConnectionintercept, который ассоциирован со свойством Intercept.
EldlnterceptPropIsNil - потомок класса EldTCPConnectionError. По-ПЫТКа установки
InterceptEnabled В true в то время, когда Intercept имеет значение Nil.
EldlnvalidServiceName - потомок класса EidException. Неправильное имя сервиса.
EldInvalidSocked - потомок класса EldException. Неожиданное закрытие соединения.
EldLoginException - потомок класса EldTelnetServerException. Ошибка при соединении
с Telnet-сервером.
EldMaxLoginAttempt - потомок класса EldLoginException. Исчерпан лимит подключений
к Telnet-серверу. Максимальное число подключений указывается в свойстве TIdTelnetServer.LoginAttempts.
EldMessageException - потомок класса EldException. Базовый класс для исключений
Indy, которые отображают сообщения об ошибке.
EldMoreThanOneTIdAntiFreeze - потомок класса EldException. Попытка создания
более одного компонента TIdAntiFreeze в вашем приложении. Приложению не требуется
больше одного такого компонента.
EldNNTPConnectionRefused - потомок класса EldProtocolReplyError. Отказ соединения
с NNTP-сервером.
EldNNTPException - потомок класса EldException. Базовый класс всех NNTP-исключений.
EldNNTPNoOnNewGroupsList - потомок класса EldNNTPException. Ошибка поиска в
новом списке Newsgroups.
EldNNTPNoOnNewNewsList - потомок класса EldNNTPException. Ошибка поиска в новом
списке сообщений NNTP.
EldNNTPNoOnNewsgroupList - потомок класса EldNNTPException. Ошибка поиска в
новом списке Newsgroups.
EldNNTPStringListNotlnitialized - потомок класса EldNNTPException. Неудачный
поиск сообщения.
EldNoBindingsSpecified - потомок класса EldODPServerException. Попытка UDP-сервера
инициализировать дескриптор сокета, но номер порта при этом не был задан.
EldNoDataToRead - потомок класса EldTCPConnectionError. Попытка записи с помощью
вызова метода Writestream пустого потока Tstream.
EldNoExecuteSpecified - потомок класса EldTCPConnectionError. Heудачное выполнение
процесса, имеющего равный приоритет с вашим приложением.
EldNoOnAuthentication - потомок класса EldTelnetServerException. У компонента
TldTelnetServer не определен обработчик события
OnAuthentication.
EldNotAllBytesSent - потомок класса EldSocketHandleError. Передача данных не
завершена. Были отправлены не все байты.
EldNotEnoughDatalnBuffer - потомок класса EldTCPConnectionError. Не достаточно
байтов во внутреннем буфере компонента
TIdTCPConnection.
EldObjectTypeNotSupported - потомок класса EldTCPConnectionError. Не поддерживаемый
тип объекта Tstream или Tstrings.
ElidOpenssLError - потомок класса EidException. Класс-предок для всех классов
исключений Open SSL.
EldOpenSSLLoadError - потомок класса EldOpenSSLError. Базовый класс ошибок загрузки
библиотеки Open SSL.
EldOSSLAcceptError - потомок класса EldOpenSSLError. Новое SSL-соединение не
доступно.
EldossLConnectError - потомок класса EldOpenSSLError. Ошибка SSL-соединения.
EldOSSLCouldNotLoadSSLLibrary - потомок класса EldOpenSSLLoadError. Невозможно
загрузить библиотеку Open SSL.
EldOSSLCreatingContextError - потомок класса EldOpenSSLError. Ошибка преобразования
содержания SSL после смены режима.
EldOSSLDataBindingError - потомок класса EldOpenSSLError. Невозможна привязка
SSL-сокета.
EldOSSLGetMethodError - потомок класса EldOpenSSLError. Компонент TidssLContext
содержит значение неверного режима.
EldOSSLLoadingCertError - потомок класса EldOpenSSLLoadError. Файл-сертификат
не может быть загружен после смены значения свойства Mode у компонента TIdSSLContext.
EldOSSLLoadingKeyError - потомок класса EldOpenSSLLoadError. Ключевой файл-сертификат
не может быть загружен после смены значения свойства Mode у компонента TidssLContext.
EldOSSLLoadingRootCertError - потомок класса EldOpenSSLLoadError. Корневой
файл-сертификат не может быть загружен после смены значения свойства Mode у
компонента TidssLContext.
EldossLModeNotset - потомок класса EldOpenSSLError. He назначен режим контекста
SSL.
EldOSSLSettingCipherError - потомок класса EldOpenSSLError. Ошибка установки
схемы шифрования SSL контекста после смены режима.
EldPackageSizeTooBig - потомок класса EldSocketHandleError. Неправильный размер
пакета.
EldProtocolReplyError - потомок класса EldException. Ошибка протокола.
EldResponceError - потомок класса EldException. Ошибка ожидаемого ответа.
EldSetSizeExceeded - потомок класса EldException. Количество вызовов FD SET
превысило мэксимум, поддерживземый операционной системой.
EldSilentException - потомок класса EldException. Молчаливое исключение. Похоже
на Eabort.
EldSockedError - потомок класса EldException. Ошибка сокета.
EldSockedHandleError - потомок класса EldException. Базовый класс для всех
ошибок дескрипторов сокетов.
EldSocksAutnError - потомок класса EldSocksError. Ошибка идентификации пользователя
на Socks-прокси.
EldSocksAuthMethodError - потомок класса EldSocksError. Неправильный или неподдерживаемый
метод идентификации пользователя на Socks-прокси.
EldSocksError - потомок класса EldException. Базовый класс исключений Socks
при использовании метода TldTCPClientConnect.
EldSocksRequestFailed - потомок класса EldSocksError. Socks-прокси отклонил
или не распознал запрос от TCP-клиента.
EldSocksRequestldentFailed - потомок класса EldSocksError. Идентификатор пользователя,
полученный от TCP-клиента, не совпадает с идентификатором, представленным программой
Ident Daemon, запущенной на компьютере пользователя.
EldSocksRequestServerFailed - потомок класса EldSocksError. Socks-прокси не
может создать соединения, запрашиваемого TCP-клиентом.
EldSocksServerAddressError - потомок класса EldSocksError. Socks-прокси не
поддерживает тип адресации, который получен от TCP-клиента.
EldSocksServerCoiranandError - потомок класса EldSocksError. Socks-прокси не
поддерживает команду, которая получена от TCP-клиента.
EldSocksServerConnectionRefusedError - потомок класса EldSocksError. Соединение,
запрашиваемое TCP-сервером, было отклонено Socks-прокси.
EldSocksServerGeneralError - потомок класса EidSocksError. Socks-прокси сообщает
об ошибке.
EldSocksServerHostUnreachableError - потомок класса EidSocksError. Хост, запрашиваемый
TCP-клиентом, недоступен.
EldSocksServerNetUnreachableError - потомок класса EldSocksError. Сеть недоступна.
EldSocksServerPermissionError - потомок класса EldSocksError. Запрашиваемое
соединение не поддерживается набором правил.
EIdSocksServerRespondError - потомок класса EldSocksError. Socks-прокси не
отвечает на запросы TCP-клиента.
EIdSocksServerTTLExpiredError - потомок класса EldSocksError. Хост нe может
быть доступным, т. к. превышен TTL.
EldSocksUnknownError - потомок класса EldSocksError. Неизвестная ошибка.
EldStackCanNotLoadWinsock - потомок класса EldException. Невозможно получить
данные из сокета.
EldstackError - потомок класса EldException. Базовый класс для ошибок стека
протокола Indy.
EldStacklnitializationFailed - потомок класса EдdstackError. Ошибка инициализации
стека протокола.
EldStackSetSizeExceeded - потомок класса EдdstackError. Превышено мзксимзльно
возможное число дескрипторов сокетов.
EldTabieNotFound - потомок класса EldException. Неверное преобразование символов
с использованием кодовой таблицы.
EldTCPConnectionError - потомок класса EldException. Базовый класс ошибок
TCP-соединений.
EldTCPServerError - потомок класса EldException. Базовый класс ошибок TCP-сервера.
EldTelnetClientConnectError - потомок класса EldTelnetError. Ошибка соединения
с Telnet-сервером.
EldTelnetError - потомок клзсса EldException. Базовый класс ошибок Indy Telnet.
EldTelnetServerException - потомок класса EldException. Базовый класс ошибок
Telnet-сервера.
EldTelnetServerOnDataAvailablelsNil - потомок класса EldTelnetError. Неверная
попытка выполнения метода TidTeinet.DoOnDataAvaiiabie.
EldTextlnvalidCount - потомок класса EldMessageException. Ошибка при создании
текстового сообщения.
EldTFTPAccessViolation - потомок класса EldTFTPEXCeption. Доступ кFTP запрещен.
EldTFTPAllocationExceeded - потомок класса EldTFTPEXCeption. Превышение распределений.
EldTFTPEXCeption - потомок класса EldException. Базовый класс для исключений
Trivial FTP.
EldTFTPFileAlreadyExists - потомок класса EldTFTPEXCeption. Попытка создзния
уже существующего файла.
EldTFTPFileNotFound - потомок класса EldTFTPEXCeption. Файл не найден.
EldTFTPIllegalOperation - потомок класса EldTFTPEXCeption. Неправильнзя FTP-операция.
EldTFTPNoSuchUser - потомок класса EldTFTPException. Ошибка Проверки имени
пользователя и пароля.
EldTFTPOptionNegotiationFailed - потомок класса EldTFTPException. Неверный
выбор согласования FTP.
EldTFTPUnknownTransferlD - потомок класса EldTFTPException. Неизвестный идентификатор
передачи данных.
EldThreadClassNotSpecified - является потомком класса EldThreadMgrError. Попытка
создания нового потока без указания имени класса.
EldThreadMgrError - потомок класса EldException. Базовый класс для ошибок Indy
Thread Manager.
EldTunnelConnectToMasterFailed - потомок класса EldTunnelException. Невозможно
соединение подчиненного и главного туннелей.
EldTunnelCRCFailed - потомок класса EldTunnelException. Неверное вычисление
CRC.
EldTunnelCustomMessagelnterpretationFailure - потомок класса EldTunnelException.
Подчиненный поток получил сообщение неизвестного типа.
EldTunnelDontAllowConnections - потомок класса EldTunnelException. Подчиненный
поток не может установить соединение.
EldTunnelException - потомок класса EldException. Базовый класс для ошибок
Indy Tunnel.
EldTunnellnterpretationOfMessageFailed - является потомком класса EldTunnelException.
Ошибка интерпретации сообщения от подчиненного потока.
EldTunnelMessageHandlingFailed - является потомком класса EldTunnelException.
Подчиненным потоком получено неправильное сообщение.
EldTunnelMessageTypeRecognitionError - является потомком класса EldTunnelException.
Неизвестный тип сообщения.
EldTunnelTransformError - потомок класса EldTunnelException. Ошибка преобразования
данных при туннельном соединении.
EldTunnelTransformErrorBeforeSend - является потомком класса EldTunnelException.
Ошибка преобразования данных до их отправки.
EldUDPException - потомок класса EldException. Базовый класс для ошибок Indy
UDP.
EldUDPReceiveErrorZeroBytes - потомок класса EldUDPException. Данные не были
получены при установленном соединении.
EldUDPServerException - потомок класса EldUDPException. Базовый класс для ошибок
Indy UDP-сервер.
EIniFileException - потомок класса Exception. Ошибка При работе с INI-файлами.
ElnOutError - потомок класса Exception. Ошибка ввода/вывода. Коды ошибок ввода/вывода
представлены в табл. 9.1.
Таблица 9.1. Коды ошибок ввода/вывода
Linux | Windows | ||
Код ошибки | Описание | Код ошибки | Описание |
2 | Нет файла или каталога | 2 | Файл не найден |
3 | Путь к файлу не найден | ||
5 | Ошибка ввода/вывода | 5 | Доступ запрещен |
13 | Доступ запрещен | ||
20 | Не является каталогом | ||
21 | Является каталогом | ||
32 | Ошибка совместного использования файла | ||
Ошибки, не зависящие от операционной
системы
|
|||
Код ошибки | Описание | ||
100 | Достигнут конец файла | ||
101 | Диск полон | ||
102 | Файловая переменная не назначена | ||
103 | Файл не открыт | ||
104 | Файл не открыт для ввода | ||
105 | Файл не открыт для вывода | ||
106 | Ошибка ввода по формату | ||
107 | Файл уже открыт |
ElntError - потомок класса EExternal. Базовый класс для целочисленных математических
ошибок.
ElntfCastError - потомок класса Exception. Неверное использование оператора
as. Дополнительные возможности Kylix
Elntoverflow - потомок класса ElntError. Превышено максимальное значение целого
числа.
ElnvalidArgument - потомок класса EMathError. Аргумент мзтемзтической функции
задан неправильно.
ElnvaiidCast - потомок класса Exception. Неверное использование оператора as.
ElnvaiidGraphic - потомок класса Exception. Нераспознаваемый графический файл.
EInvalidGraphicOperation - потомок класса Exception. Неверное использование
графических операций.
EInvalidGridOperation - потомок класса Exception. Неверное использование сетки
(Grid).
ElnvaiidHandleException. Базовый класс для ошибок при оперировании объектами
TFont, TPen и Thrush.
EInvalidlmage - потомок класса EFilerError. Невозможно прочитать файл ресурсов.
ElvalidOp - потомок класса EMathError. Неизвестная операция с плавающей запятой.
ElnvalidOperation - потомок класса Exception. Неверное действие над компонентом.
Примечание
Не путайте классы исключений ElnvaiidOp и ElnvalidOperation!
ElnvalidParam - базовый класс для неверных потоковых операций с ресурсами mime.
Elnvalidpointer - потомок класса EHeapException. Неверная операция над указателем.
EMaskException - потомок класса Exception. Ошибка сравнения имени файла по
маске.
EMathError - потомок класса EExternai. Абстрактный класс исключений для математических
операций над вещественными числами.
EMenuError - потомок класса Exception. Ошибка при работе с системным меню.
EOutofMemory - потомок класса EHeapException. Ошибка распределения памяти.
EOutOfResources - потомок классз EOutofMemory. Ошибка распределе-ния дескрипторов
окон.
EOverflow - потомок класса EMathError. Превышено максимально возможное вещественное
значение.
EPackageError - потомок класса Exception. Ошибка загрузки или уничтожения пакета.
EParserError - потомок класса Exception. Ошибка преобразования текста в двоичную
форму.
EPrinter - потомок класса Exception. Ошибка вывода на печатающее устройство.
EPrivilege - потомок класса EExternai. Попытка выполнения инструкции процессора,
которая является недоступной при данном уровне привилегий процессора.
EPropertyConvertError - потомок класса Exception. Ошибка установки или получения
значения свойства компонента.
EPropertyError - потомок класса Exception. Ошибка при установке нового значения
свойства компонента.
EQtoiaiogException - потомок класса Exception. Ошибка при работе с Qt-диалогом.
ERangeError - потомок класса ElntError. Значение целочисленной переменной превысило
максимально возможное.
EReadError - потомок класса EFilerError. Ошибка чтения данных из потока.
EReconcileError - потомок класса EDBciient. Ошибка обновления набора данных
клиента.
ERegisterActionsException - потомок класса Exception. He произведена инициализация
регистрации системы.
EResNotFound - потомок класса Exception. Ошибка работы с файлами ресурсов.
ESafecallException - потомок класса Exception. Ошибка при выполнении безопасного
вызова процедуры.
ESocketError - потомок класса Exception. Ошибка инициализации или отключения
сокета.
EstackOverfiow - потомок класса EExternali. Переполнение стека.
EstreamError - потомок класса Exception. Базовый класс ошибок, связанных с
потоками.
EstringListError - потомок класса Exception. Неверная работа со списком.
EThread - потомок класса Exception. Ошибка синхронизации потоков.
ETreeViewError - потомок класса Exception. Неверная работа с деревом.
EUnderflow - потомок класса EMathError. Вещественное значение слишком мало.
EUpdateError - потомок класса EDatabaseError. Ошибка обновления набора данных сервера.
EVariantError - потомок класса Exception. Ошибка при работе с типом данных
Variant.
EWebBrokerException - потомок класса Exception. Ошибка при работе с объектом
WebBroker.
EWriteError - потомок класса EFilerError. Ошибка при записи данных в поток.
EZeroDivide - потомок класса EMathError. Ошибка деления вещественного числэ
на ноль.
Защита ресурсов и регенерация исключений
Иногда бывает необходимо после обработки исключительной ситуации вызвать стандартный
обработчик ошибки. Например, в случае возникновения некоторой ошибки вы хотите,
чтобы приложение сообщало пользователю какую-либо информацию, а затем передавало
управление стандартному обработчику ошибок. Как вы уже знаете, после обработки
исключения вашим кодом исключение уничтожается. Для того чтобы самостоятельно
вызвать снова это исключение, можно воспользоваться регенерацией исключений.
Для регенерации исключения служит команда raise, рассмотренная в листинге 9.5.
Листинг 9.5. Регенерация исключения !
try
{ операторы } except
on <класс исключения> do
begin
{операторы обработки исключения}
raise; // Регенерация исключения
end;
end;
После выполнения операторов обработки исключения, написанных программистом,
выполняется команда raise, которая снова принудительно вызывает это исключение,
после чего управление передается стандартному обработчику исключений.
В случае, если исключение успешно проходит через все блоки try в коде приложения,
вызывается метод HandieException. Он показывает диалоговое окно ошибки. Вы можете
вызвать этот метод так, как показано в листинге 9.6.
Листинг 9.6. Вызов метода HandieException
try
{ операторы }
except
Application.HandieException(Self);
end;
Теперь рассмотрим конструкцию, предназначенную для защиты ресурсов приложения.
Конструкция try ... finally служит для защиты кода, записанного в разделе finally
от исключительных ситуаций, которые в силу каких-либо причин могут происходить
в разделе try. Синтаксис этой конструкции представлен в листинге 9.7.
Листинг 9.7. Конструкция try ... finally
try
(операторы, способные создать исключительную ситуацию};
finally
{защищенные операторы, выполняемые в любом случае};
end;
Таким образом, операторы, которые размещены после ключевого слова finally, будут
выполняться в любом случае, независимо от того, была сгенерирована исключительная
ситуация или нет.
Если в разделе try была сгенерирована исключительная ситуация, то управление
немедленно передается разделу finally. Если исключительной ситуации в разделе
try не было, блок finally все равно будет выполняться. Даже если в разделе finally
произойдет ошибка, выполнение операторов этого раздела будет продолжено до конца
без выдачи сведений об ошибке.
В конструкции try . .. finally не происходит обработки исключений, она используется
в основном для освобождения ресурсов памяти. Таким образом, в данной конструкции
нуждаются операции с файлами, памятью, ресурсами операционной системы и объектами.
Код обработки исключения можно разбить на блоки try ... except ... end и try
. . . finally .. . end. Эти блоки могут быть вложенными (рис. 9.3).
Рис. 9.3. Вложенные блоки в обработчике исключений (а) и в конструкции
защиты кода (б)
При разработке приложений в среде Kylix могут возникнуть ситуации, когда программисту
не требуется обрабатывать исключения, а необходимо лишь прервать нежелательное
действие, вызывающее ошибку. Для этого применяются так называемые молчаливые
исключения (silent exceptions).
Молчаливые исключения - это исключения, которые не отображают на экране сведений
о том, что произошла ошибка. В результате будет пропущена команда, которая вызвала
исключение, и приложение будет работать дальше.
Молчаливые исключения являются потомками стандартного исключения EAbort. По
умолчанию обработчик ошибок CLX Kylix отображает на экране диалоговое окно ошибки
для всех исключений, кроме наследников EAbort.
Примечание
При создании консольных приложений сведения об ошибке выводятся и для необработанных
исключений EAbort.
Для того чтобы сгенерировать молчаливое исключение, можно вызвать процедуру
Abort. Она автоматически сгенерирует исключение EAbort, которое oрервет текущую
операцию без вывода сведения об ошибке на экран. Рассмотрим пример. Пусть форма
содержит пустой список ListBox1 и кнопку Button 1 (рис. 9.4).
Рис. 9.4. Форма с пустым списком и кнопкой Button 1
Запишем в обработчик события кнопки Onclick следующий код (листинг 9.8):
Листинг 9.8. Генерация молчаливого исключения
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
for I := 1 to 10 do (цикл 10 раз}
begin
ListBox1.Items.Add(IntToStr(I)); (добавляем номер в список)
if I = 7 then Abort; {прерьшаем добавление номеров в список после
ВЦ добавления седьмого номера}
end;
end;
Запустим программу. В результате работы программы, после нажатия кнопки Button1,
в список будет добавлено семь строк с номерами от 1 до 7 (рис. 9.5).
Рис. 9.5. Результат выполнения программы генерации молчаливого исключения
Если нажать кнопку несколько раз, то в список будут добавлены новые строки
с номерами от 1 до 7 после имеющихся (рис. 9.6).
Рис. 9.6. Результат многократного нажатия кнопки Button 1
Генерация исключений
Иногда программисту необходимо, чтобы программа в нужный момент времени генерировала
исключительную ситуацию нового типа, которого нет в стандартных типах исключений
Kylix. В этом случае следует создать новый тип исключения.
Для создания собственных типов исключений нужно знать, как определить тип объекта
исключения и как вызвать исключение.
Так как исключение является объектом Kylix, то определение нового типа исключения
так же просто, как определение объекта нового типа. Теоретически возможно вызвать
любой объект как объект исключения, но стандартные обработчики исключений работают
только с теми объектами, которые являются потомками Exception или, другими словами,
с объектами, предками которых являются Exception.
В качестве примера создания собственного типа исключения рассмотрим следуюшее
определение:
tуре
EMyException = class (Exception);
Теперь, если вы вызовете исключение EMyException, но не напишите собственный
обработчик для него, произойдет вызов стандартного обработчика для Exception.
Так как стандартный обработчик для Exception показывает имя названного исключения,
вы можете увидеть имя вашего нового исключения.
Чтобы вызвать созданное исключение, используйте команду raise.
Для примера рассмотрим типичную задачу проверки введенного пользователем пароля:
tуре
EPasswordlnvalid = class(Exception);
После определения нового типа исключения EPasswordinwalid вы можете вызвать
это исключение в любом месте программы:
lf Password <> CorrectPassword then
raise EPasswordlnvalid.Create('Введен неправильный пароль');
Вызов созданного исключения производится по его имени. При этом вызывается метод
конструктора Create. Уничтожать самостоятельно вызванное исключение не нужно,
т. к. об этом позаботится среда Kylix.
Когда тот или иной физик использует понятие "физический вакуум", он либо не понимает абсурдности этого термина, либо лукавит, являясь скрытым или явным приверженцем релятивистской идеологии.
Понять абсурдность этого понятия легче всего обратившись к истокам его возникновения. Рождено оно было Полем Дираком в 1930-х, когда стало ясно, что отрицание эфира в чистом виде, как это делал великий математик, но посредственный физик Анри Пуанкаре, уже нельзя. Слишком много фактов противоречит этому.
Для защиты релятивизма Поль Дирак ввел афизическое и алогичное понятие отрицательной энергии, а затем и существование "моря" двух компенсирующих друг друга энергий в вакууме - положительной и отрицательной, а также "моря" компенсирующих друг друга частиц - виртуальных (то есть кажущихся) электронов и позитронов в вакууме.
Однако такая постановка является внутренне противоречивой (виртуальные частицы ненаблюдаемы и их по произволу можно считать в одном случае отсутствующими, а в другом - присутствующими) и противоречащей релятивизму (то есть отрицанию эфира, так как при наличии таких частиц в вакууме релятивизм уже просто невозможен). Подробнее читайте в FAQ по эфирной физике.