Интернет магазин музыки, mp3 почтой, заказать mp3 диски

баннер интернет-магазина ножей nifovka.ru

RSS - RSS,
Карта сайта

Rambler's Top100

Написать на e-mail © 2007-2012 г.



Теги страницы:

Пишите для ошибок catch так рано, как это возможно, но не раньше. Очевидно, что вы не захотите отлавливать ошибку до того, как вы сможете что-то с ней сделать. Код, который обнаруживает ошибки, должен быть достаточно высоко расположен в цепи команд, чтобы он мог решить, что следует делать, если что-то идет не так. Вот пример, иллюстрирующий это правило. Представьте, что вы пишете код, который должен считывать wave файл и сохранять его в классе CSound. У вас есть несколько настроенных функций.

Вверху находится функция rnain{) вашей C++ программы. Функция mam() вызывает LoadGameResources - большую функцию, ответственную за загрузку всех картинок, музыки и уровней, та в свою очередь, вызывает LoadSoundFile, которая, в свою очередь, вызывает Load Wave File для загрузки wave файлов. Теперь предположите, что LoadWaveFile выполняет команду fopen, чтобы открыть файл. И команде fopen это сделать не удается (представьте, что файла, который она хочет открыть, на диске нет). Вы используете исключительные ситуации, поэтому вы решаете, что, если fopen ошибется, нужно это обработать с помощью throw.

Золотое правило номер один говорит, что если вы пишете throw, вы пишете и catch, поэтому теперь вы должны решить, где будет располагаться catch. Есть несколько мест, где это можно сделать: в функции LoadWaveFile; в функции LoadSoundFile; в функции LoadGameResources; в самом начале, в функции main(). Начнем с того, что подумаем о LoadWaveFile. Что эта функция может сделать в catch обработке? К сожалению, практически ничего. LoadWaveFile не знает, почему загружается файл, поэтому не может нормально решить, что делать, если что-то не так. В качестве контрпримера вы можете предложить, чтобы LoadWaveFile обнаруживал ошибку и выходил с помощью вызова. Для игры это еще, может быть, и ничего, но представьте себе, что вы хотите использовать LoadWaveFile в приложении, обрабатывающем звук.

Пожалуй, это не будет иметь смысла, так как ваше приложение будет выключаться, теряя все, сделанное пользователем, только потому, что запрашиваемого файла нет на диске. Было бы лучше, если бы выдавалось сообщение «Файл не найден» и пользователь продолжал свою работу с приложением. Суть в том, что LoadWaveFile - это просто служебная функция, очень маю знающая о контексте программы. Далее, продвигаясь вверх по стеку, как насчет LoadSoundFile? LoadSoundFile уже ближе, но не еще не достаточно хороша. Ей так же, как и предыдущей, не хватает информации. Следующей идет функция LoadGameResources. Это первая точка, где вы обладаете достаточным контекстом, чтобы выяснить, что делать. LoadGameResources знает, что, если вы не сможете положить те байты, которые вам нужно, с диска на RAM, игра не будет идти так, как она задумана. В этой функции вы можете написать в коде, чтобы появлялось сообщение, требующее, переустановки игры игроком, или вы можете попытаться выпутягься из ситуации иначе (например, посмотреть, вставлен ли диск в дисковод, и, если это так, считать оставшуюся информацию с него).

В заключение, а почему бы не вставить catch в main? Конечно же, вы можете обработать ошибку и здесь, но я могу поспорить с вами, что это слишком высоко по стеку. До некоторой степени это голос здравого смысла: конечно, это не будет концом света, если вы будете отлавливать ошибку здесь, однако main, обрабатывающая такую ошибку, - это как если бы вытолкнул из машинного зала рабочих и стал чинить двигатель самостоятельно. Функция main не должна заботиться о внутренней работе загрузки ресурсов. Итак, если бы LoadCiameResoui'ces обнаружила ошибку и попыталась с ней справиться и все равно оставались бы проблемы, main могла бы обработать переданную ей в гаком случае ошибку. Этот код был бы похож на главного чиновника, говорящего главному администратору своей компании; «Посмотрите, у нас есть вот такая главная проблема, и сам я не в состоянии ее решить, хотя я пытался, и мне нужен ваш совет, чтобы двигаться дальше».

Умение находить лучшее место для отлавливания ошибок - это одно из тех умений, которые приходят только с опытом. Есть, конечно, какие-то руководства, но они подходят не для всех ситуациях. В общем, гораздо хуже отлавливать ошибку «слишком низко» (слишком близко к тому месту, где она нежели «слишком высоко», особенно в программировании игр. В игровом программировании ошибки часто вызывают остановку, поэтому отлавливание их на высшем уровне рационально. Даже если все, что вы делаете, — это отлавливаете ошибки в main, выдавая сообщение вроде «this game crashed», и дальше делаете то, что, возможно, это гораздо лучше, чем я встречал в некоторых профессионально сделанных играх, которые часто просто выгружаются с нарушением доступа, оставляя мою систему в совершеннейшем беспорядке.

В игре также существует правило наименьших затрат: часто сделать «наиболее правильную вещь» требует длинного кода и практически не имеет особой пользы (если вы занимаетесь не оборудованием жизнеобеспечения и не управлением шаттлов). В программировании игр доверяйте своему внутреннему чувству и не заботьтесь о том, чтобы оно было абсолютно верно.