6.8 Селекторы

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

Работа функции селектора не меняется с главы 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);

}

 

Возможно, есть небольшой перебор с проверками, но у нас есть универсальный и надёжный интерфейс.

 

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