6.4 Наследование — Any

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

Имя описания Class и Object уже можно создавать новые объекты и даже новый подкласс. В качестве примера рассмотрим подкласс Any, который утверждает, что все его объекты равны любому другому объекту, то есть Any перезаписывает differ() так, чтобы всегда возвращать ноль. Вот реализация Any и быстрый тест, всё в одном файле any.c:

 

#include "Object.h"

 

static int Any_differ (const void * _self, const void * b)

{

    return 0; /* Any равны чему угодно... */

}

 

int main () {

    void * o = new(Object);

    const void * Any =

                    new(Class, "Any", Object, sizeOf(o),

                        differ, Any_differ,

                        0);

 

    void * a = new(Any);

 

    puto(Any, stdout);

    puto(o, stdout);

    puto(a, stdout);

 

    if (differ(o, o) == differ(a, a))

        puts("ok");

 

    if (differ(o, a) != differ(a, o))

        puts("not commutative");

 

    delete(o), delete(a);

    delete(Any);

 

    return 0;

}

 

Если мы реализуем новый класс, то должны подключать интерфейс суперкласса. Any имеет такое же представление, как Object, и этот класс настолько прост, что даже не нужно подключать файл представления суперкласса. Описание класса Any создаётся запросом нового экземпляра его метакласса Class и конструирования его с новым именем класса, описанием суперкласса и размером объекта нового класса:

 

const void * Any =

                new(Class, "Any", Object, sizeOf(o),

                    differ, Any_differ,

                    0);

 

Дополнительно указываются только те динамически компонуемые методы, которые переписаны для нового класса. Имена методов могут появляться в любом порядке, каждому предшествует селектор имени. Список завершается нулём.

Программа генерирует один экземпляр o класса Object и один экземпляр a класса Any, и отображает описание нового класса и двух экземпляров. Любой экземпляр не может отличаться от самого себя, поэтому программа печатает ok. Метод differ() для Any был переписан; Поэтому получаем разные результаты сравнивая o с a, и наоборот:

 

$ any

Class at 0x101fc

Object at 0x101f4

Any at 0x10220

ok

not commutative

Any: cannot destroy class

 

Ясно, что мы не должны быть в состоянии удалить описание класса. Эта ошибка обнаруживается уже во время компиляции, так как delete() не принимает указатель на область, защищённую с помощью const.

 

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