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

2.6 Другая реализация — Atom

2.6 Другая реализация — Atom

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

Для иллюстрации того, что можно сделать с помощью интерфейса конструктора и деструктора мы реализуем атомы. Атом является уникальным строковым объектом; если два атома содержат одни и те же строки, они идентичны. Атомы очень дёшевы для сравнения: differ() возвращает истину, если указатели двух аргументов отличаются. Атомы более дорогостоящи для создания и уничтожения: мы храним круговой список всех атомов и учитываем, сколько раз какой-либо атом был клонирован:

 

struct String {

    const void * class;   /* должен быть первым */

    char * text;

    struct String * next;

    unsigned count;

};

 

static struct String * ring; /* всех строк */

 

static void * String_clone (const void * _self) {

    struct String * self = (void *) _self;

 

    ++ self -> count;

    return self;

}

 

Наш круговой список всех атомов запоминается в ring, увеличиваясь через поле .next компонента, и поддерживается с помощью конструктора и деструктора строки. Перед тем как конструктор сохраняет текст, он сначала просматривает список, чтобы увидеть, был ли уже сохранён этот текст. В начало String_ctor() вставлен следующий код:

 

if (ring) {

    struct String * p = ring;

    do

        if (strcmp(p -> text, text) == 0) {

            ++ p -> count;

            free(self);

            return p;

    }

    while ((p = p -> next) != ring);

}

else

    ring = self;

 

self -> next = ring -> next, ring -> next = self;

self -> count = 1;

 

Если мы находим подходящий атом, то увеличиваем его счётчик ссылок, освобождаем память новой строки объекта self и вместо неё возвращаем атом p. В противном случае мы вставляем новый объект строки в круговой список и устанавливаем его счётчик ссылок в 1.

Деструктор предотвращает удаление атома до тех пор, пока его счётчик ссылок не уменьшится до нуля. В начало String_dtor() вставлен следующий код:

 

if (-- self -> count > 0)

    return 0;

 

assert(ring);

if (ring == self)

    ring = self -> next;

if (ring == self)

    ring = 0;

else {

    struct String * p = ring;

 

    while (p -> next != self) {

        p = p -> next;

        assert(p != ring);

    }

    p -> next = self -> next;

}

 

Если уменьшаемый счётчик ссылок положителен, возвращается нулевой указатель, чтобы delete() оставила наш объект нетронутым. В противном случае мы очищаем маркер кругового списка, если наша строка была последней, или убираем строку из списка.

Реализация нашего приложения из раздела 2.4 замечает, что клонированная строка идентична оригиналу и печатает

 

sizeOf(a) == 16

ok

clone?

 

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