6.8 Селекторы |
Предыдущая Содержание Следующая |
Работа функции селектора не меняется с главы 2: один из аргументов, _self, является объектом для динамической компоновки. Проверяем, что она существует и что искомый метод существует для данного объекта. Затем вызываем метод и передаём ему все аргументы; поэтому метод может считать, что _self является подходящим объектом для него. И, наконец, возвращаем значение результата метода, если таковой имеется, в виде результата селектора. Каждый динамически скомпонованный метод должен иметь селектор. До сих пор обращения к конструктору и деструктору скрывались за new() и delete(), но нам по-прежнему нужны имена функций ctor и dtor для пар селектор / метод, передаваемых в конструктор Class. Мы можем позже принять решение компоновать new() и delete() динамически; таким образом, использовать их имена вместо ctor и dtor было бы не очень хорошей идеей. Для всех наших классов мы ввели общий суперкласс Object и дали ему некоторую функциональность, упрощающую реализацию селекторных функций. classOf() проверяет объект и возвращает ненулевой указатель на его описание класса. Это позволяет сделать следующую реализацию для delete():
void delete (void * _self) { if (_self) free(dtor(_self)); }
void * dtor (void * _self) { const struct Class * class = classOf(_self);
assert(class -> dtor); return class -> dtor(_self); }
new() должна быть реализована более тщательно, но работает аналогично:
void * new (const void * _class, ...) { const struct Class * class = _class; struct Object * object; va_list ap;
assert(class && class -> size); object = calloc(1, class -> size); assert(object); object -> class = class; va_start(ap, _class); object = ctor(object, & ap); va_end(ap); return object; }
Проверяем описание класса и удостоверяемся, что можно создать заполненный нулями объект. Затем инициализируем описание класса объекта и мы готовы предоставить обычному селектору ctor() найти и выполнить конструктор:
void * ctor (void * _self, va_list * app) { const struct Class * class = classOf(_self);
assert(class -> ctor); return class -> ctor(_self, app); }
Возможно, есть небольшой перебор с проверками, но у нас есть универсальный и надёжный интерфейс.
|
Предыдущая Содержание Следующая |