Windows

       

Funcarama4: последний рубеж


Настоящая проблема в Fипсаrата3 — расплата за изящество. Я уже говорил: избегай те по возможности операторов return внутри блока try.

Чтобы облегчить последнюю задачу, Microsoft ввела еще одно ключевое слово в свой компилятор С++- _leave. Вот новая версия (Funcarama4), построенная на при менении нового ключевого слова:

BOOL Funcarama4() {

// Внимание, инициализируйте все переменные, предполагая худшее

HANDLE hFile = INVALID_HANDLE_VALUE;

PVOID pvBuf = NULL;

// предполагаем, что выполнение функции будет неудачным BOOL fFunctionOk = FALSE;

__try {

DWORD dwNumBytesRead;
BOOL fOk;

hFile = CreateFile("SOMEDATA.DAT", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID,HANDLE_VALUE)
{
__leave;
}

pvBuf = VirtualAlloc(NULL, 1024, MEM_COHMIT, PAGE_READWRITE);

if (pvBuf == NULL)
{
__leave;
}

fOk = ReadFile(hFile, pvBuf, 1024, &dwNumBytesRead, NULL);
if (!fOk (dwNumBytesRead == 0))
{
__leave;
}

// что-то делаем с данными
// функция выполнена успешно fFunctionOk = TRUE; }

__finally
{
// очистка всех ресурсов
if (pvBuf != NULL)
VirtualFree(pvBuf, MEM_RELEASE | MEM__DECOMMIT);

if (hFile != INVALID_HANDLE_VALUE)

CloseHandle(hFile);
} // продолжаем что-то делать

return(fFunctionOk);
}

Ключевое слово _leave в блоке try вызывает переход в конец этого блока. Може те рассматривать это как переход на закрывающую фигурную скобку блока try. И никаких неприятностей это не сулит, потому что выход из блока try и вход в блок finally происходит естественным образом. Правда, нужно ввести дополнительную бу леву переменную fFunctionOk, сообщающую о завершении функции: удачно оно или нет. Но это дает минимальные издержки.

Разрабатывая функции, использующие обработчики завершения именно так, ини циализируйте все описатели ресурсов недопустимыми значениями перед входом в блок try. Тогда в блоке finally Вы проверите, какие ресурсы выделены успешно, и узна ете тем самым, какие из них следует потом освободить. Другой распространенный

метод отслеживания ресурсов, подлежащих освобождению, — установка флага при успешном выделении ресурса. Код finally проверяет состояние флага и таким обра зом определяет, надо ли освобождать ресурс,



Содержание раздела