The website "dmilvdv.narod.ru." is not registered with uCoz.
If you are absolutely sure your website must be here,
please contact our Support Team.
If you were searching for something on the Internet and ended up here, try again:

About uCoz web-service

Community

Legal information

9.1 Инициализация

9.1 Инициализация

Предыдущая  Содержание  Следующая V*D*V

Описания классов — долгоживущие объекты. Они постоянны и существуют практически так же долго, как приложение выполняется. Такие объекты по возможности инициализируются во время компиляции. Однако в главе 6 мы решили, что статическая инициализация делает описания классов трудными для сопровождения: порядок компонентов структур должен быть согласован со всеми инициализациями, а наследование вынудило бы нас раскрыть динамически компонуемые методы за пределами их файлов реализации.

Для начальной загрузки мы инициализируем во время компиляции только описания Object и Class как статические структуры в файле Object.dc. Все другие описания классов генерируются динамически, а конструкторы метаклассов, начиная с Class_ctor(), заботятся о наследовании и перезаписи динамически компонуемых методов.

ooc генерирует функции инициализации, чтобы скрыть детали вызова new() для генерации описаний классов, но факт того, что они должны явно вызываться в коде приложения, является источником трудно диагностируемых ошибок. Например, рассмотрите initPoint() и initCircle() из раздела 6.10:

 

void initPoint (void) {

    if (! PointClass)

        PointClass = new(Class, "PointClass",

                Class, sizeof(struct PointClass),

                ctor, PointClass_ctor,

                0);

    if (! Point)

        Point = new(PointClass, "Point",

                Object, sizeof(struct Point),

                ctor, Point_ctor,

                draw, Point_draw,

                0);

}

 

Эта функция разработана, чтобы выполнить свою работу лишь однажды, то есть даже если она будет вызвана несколько раз, она создаст только один экземпляр каждого описания класса.

 

void initCircle (void) {

    if (! Circle) {

        initPoint();

        Circle = new(PointClass, "Circle",

                Point, sizeof(struct Circle),

                ctor, Circle_ctor,

                draw, Circle_draw,

                0);

    }

}

 

Обе функции неявно соблюдают иерархию классов: initPoint() удостоверяется, что PointClass существует, прежде чем использовать его для генерации описания Point; вызов initPoint() в initCircle() гарантирует, что описание суперкласса Point и его описание метакласса PointClass существуют, прежде чем они будут использованы для генерации описания Circle. Опасности рекурсии нет: initCircle() вызывает initPoint(), потому что Point это суперкласс Circle, но initPoint() не будет ссылаться на initCircle(), потому что ooc не разрешает циклы в отношениях между суперклассами.

Однако, всё пойдёт ужасно неправильно, если мы когда-нибудь забудем проинициализировать описание класса до того, как будем его использовать. Поэтому в этой главе мы рассмотрим механизмы, которые автоматически предотвратят эту проблему.

 

Предыдущая  Содержание  Следующая