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

6.5 Реализация — Object

6.5 Реализация — Object

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

Реализация класса Object прямолинейна: конструктор и деструктор возвращают self, а differ() проверяет, являются ли указатели двух его аргументов равными. Определения этих тривиальных реализаций являются, однако, очень важными: мы используем одно дерево классов и делаем Object конечным суперклассом любого другого класса; если какой-то класс не перезаписывает какой-то метод, например differ(), он наследует его от Object, то есть каждый класс имеет по крайней мере простейшее определение для каждого динамически компонуемого метода уже применимого к Object.

Это общий принцип безопасности: всякий раз вводя новый динамически компонуемый метод, мы будем немедленно реализовывать его для этого первого класса. Таким образом мы никогда сможем попасть в ловушку, выбрав совершенно неопределённый метод. Наглядным примером является метод puto() для Object:

 

static int Object_puto (const void * _self, FILE * fp) {

    const struct Class * class = classOf(_self);

 

    return fprintf(fp, "%s at %p\n", class -> name, _self);

}

 

Каждый объект указывает на описание класса,и мы сохранили имя класса с описанием. Таким образом, для любого объекта можно по крайней мере показать имя класса и адрес объекта. Первые три строки вывода из тривиальной тестовой программы в разделе 6.4 показывают, что мы не потрудились переписать этот метод для Class или Any.

puto() полагается на функцию доступа classOf(), которая выполняет некоторые проверки безопасности и возвращает дескриптор класса объекта:

 

const void * classOf (const void * _self) {

    const struct Object * self = _self;

 

    assert(self && self -> class);

    return self -> class;

}

 

Аналогичным образом можно запросить объект о его размере (* Орфография, вероятно, будет порождать ошибки, но я просто не мог удержаться от каламбура. Изобретение хороших имён методов это искусство) — помните, что в ANSI-C технически объект является простым void *:

 

size_t sizeOf (const void * _self) {

    const struct Class * class = classOf(_self);

 

    return class -> size;

}

 

Спорно, следует ли запрашивать объект о размере, или же следует спрашивать его только о классе, а затем явно запрашивать класс о размере. Если мы реализуем sizeOf() для объектов, то не сможем применить его к описанию класса, чтобы получить соответствующий размер объекта — мы получим размер описания самого класса. Тем не менее, практика показывает, что определение sizeOf() для объектов является предпочтительным. super() наоборот является статически скомпонованным методом, который возвращает суперкласс класса, а не объекта.

 

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