Программирование на языке MFC

Мой второй блог в серии программирования

Ненулевое значение


Метод производит считывание номера схемы класса и длины названия класса без учета завершающего нулевого байта, после чего в выделенный для названия класса символьный массив чита­ет название класса. Если указанное в архиве число символов в на­звании класса превышает размер выделенного для него буфера или же при считывании из архива было считано меньше, чем ука­зано, байтов, то метод немедленно возвращает NULL. После того как название класса считано, к нему дописывается нулевой байт, т. е. с этого момента название класса становится обычной строкой, завершающейся нулевым байтом. Затем метод проверяет, описан ли класс, название которого прочитано в архиве, в текущем про­цессе. Если класс не описан, то метод возвращает значение NULL. Таким образом, если: а) длина имени сохраненного класса равна 64 байтам или больше; б) если при считывании имени класса произошла какая-то ошибка и было считано меньше символов, чем указано; в) класс не описан в вызывающем модуле, то метод CRuntime::Load() возвращает значение NULL. Если же все про­верки прошли нормально, то возвращается указатель на инфор­мацию времени выполнения того класса, имя которого совпадает и именем считанного из архива класса, и управление опять пере­ходит в метод ReadClassQ. Таким образом, если метод CRuntimeClass::Load() возвратил ненулевое значение, то это яв­ляется признаком того, что в процессе, осуществляющем чте­ние из архива, класс, описание которого только что было счи­тано из архива, также описан и процесс готов работать с объ­ектами данного класса.

Если метод CRuntimeClass::Load() вернул значение NULL, это означает, что произошла ошибка, которую метод ReadClass() са­мостоятельно устранить не в состоянии. Естественный выход для метода ReadClass() в этой ситуации – выработка исключения, что он и делает. Если же загрузка прошла нормально, то начинается проверка соответствия схем (версий) классов, ведь вполне веро­ятно, что в программе используется описание более новой версии класса, чем сохраненная в архиве, верно?

Если схемы класса в вызывающем модуле и в считанной из ар­хива информации не совпали и при этом не указано, что класс мо­жет загружать информацию разных версий, то вырабатывается ис­ключение. В том случае, если схемы не совпадают, но указано, что класс может загружать информацию разных версий, для хранения несовпадающих версий заводится новая хэш-таблица, указатель на нее записывается в поле mjDSchemaMap. Ключами в этой таб­лице служат указатели на информацию времени выполнения клас­са, считанного из архива, а значения, которые принимают элемен­ты, равны номерам схем считанных из архива классов. Здесь я не поленюсь лишний раз повторить, что хэш-таблица заводится для хранения ТОЛЬКО тех схем, номера которых НЕ СОВПАДАЮТ со схемой класса, информация о котором передана методу в качестве аргумента.

Раз заведена хэш-таблица, то как же обойтись без проверки числа элементов в ней при помощи метода CheckCount()? А после проверки указатель на информацию времени исполнения класса записывается в очередной свободный элемент массива указателей, который был заведен при вызове метода MapObject(). Естественно, число элемен­тов в этом массиве увеличивается на единицу. *

Тем самым мы завершили обработку описания впервые встре­тившегося класса. А что происходит в тех случаях, когда мы счи­тываем ссылки на ранее встречавшиеся описания классов? Если индекс ранее встречавшегося класса не равен нулю (если читатель помнит, то нулевой элемент массива инициализируется значением NULL) и не превышает верхнего индекса массива (индекс в таком случае просто лишен смысла), из элемента массива с указанным индексом выбирается информация времени исполнения класса…

Так… А почему мы постоянно говорим о массиве? Дело в том, что индекс, с которым элемент был добавлен в ХЭШ-ТАБЛИЦУ при записи в архив, может использоваться как индекс МАССИВА при считывании из архива. Ведь в данном случае нам не нужно осуществлять массу проверок, верно? И для хранения данных вполне достаточно массива, доступ к элементам которого можно осуществлять по индексам, верно?

Похожие статьи: