Объекты в чистом Си, но код странный может объясните

Тема в разделе "WASM.ZEN", создана пользователем Fallout, 21 окт 2004.

  1. Fallout

    Fallout New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2004
    Сообщения:
    94
    Адрес:
    Russia
    Вообщем я никак не могу понять .. как такое происходит компилятор не выдаёт не единой ашибки (любой ANSI C) ... и самое главное всё рбаотает...



    качать тут:

    hxxp://0xC0DE.fatal.ru/files/StrObj_LCC.zip



    структура

    struct tagString {

    StringVtbl * lpVtbl; // the vtbl

    int magic; // used to verify that the struct has been initialised

    char * user; // pointer to array of chars to hold the C string

    int max; // max capacity (num chars)

    int len; // current length of C string

    };



    первое поле это ссылка на таблицу функций... так вот а теперь чудеса по коду вызывается так....



    typedef tagString String;



    String my = NewString("All the world");

    printf("%s\t%d\n\n", my.StrGet(), my.StrLen());



    // StrFree free's the array of chars and sets internal vars

    my.StrFree();



    это лишь часть чуда +).... поглядите код... может там всё логично и просто но я не понимаю ввообще +)
     
  2. Volynkin

    Volynkin New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2004
    Сообщения:
    30
    ну тут явно наблюдается множественная наследовательность... вот только будучи родной для С++ и являясь одной из основ ООП, она явно чужда для традиционного С. Вот люди и пытаются приспособить ее таким образом для Си.



    Основная идея в том, что нужно попытаться выполнить полиморфизм/виртуальные функции/наследовательности через обычные сишные указатели. Что и наблюдается в "StringVtbl * lpVtbl".

    В этом коде сперва создается Объект №1 с указателем на виртуальную таблицу методов и этот объект является основным. Он имеет свои данные и методы. Далее, String это Объект №2, который наследует Объект №1 таким образом, что в Объекте №2 сперва идут данные Объекта №1 а затем уже его собвственные. Вот только Объект №2 также имеет указатель на свою собственную виртуальную таблицу функций, чтобы защитить свои данные от передачи в вышестоящий объект №1 (инкапсуляция). Ну и так далее, тут все просто.



    Интересное же начинается во втором уровне наследования. Чтобы такое провернуть в Си, необходимо чтобы Объект №3(my), наследуя не только Объект #1 (tagString) но и Объект №2(String), был построен таким образом, чтобы он включал в себя оба(!) объекта-предка с их указателями и данными(!). Но так как Объект №3(my) должен вести себя точно также как и его родитель Объект №2(String), указатель виртуальной таблицы Объекта №2 (внутри Объекта №3) должен указывать в виртуальную таблицу Объекта №3(my), но только в то ее место, где лежит оффсет Объекта №2(String). Таким образом твой Объект №3(my) это есть структура, содержащая в себе все объекты-прородители идущие в прямой последовательности. Так и осуществляется использование "my" не только там где ожидается "tagString", но и там где ожидается "String".



    Вообще, по этому поводу есть отличная статья на http://ldeniau.home.cern.ch/ldeniau/html/oopc/oopc.html

    там смотри в особенности смотри Single и Multiple Inheritance в http://ldeniau.home.cern.ch/ldeniau/html/oopc/oopc.html#Object_Model
     
  3. volodya

    volodya wasm.ru

    Публикаций:
    0
    Регистрация:
    22 апр 2003
    Сообщения:
    1.169
    Вообще, по этому поводу есть отличная статья



    Спасибо за линк. Обезбашенная штука. Мне понравилось.
     
  4. Fallout

    Fallout New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2004
    Сообщения:
    94
    Адрес:
    Russia
    По поводу того кода который я выложил можете сума не сходить... мм всё выяснилось... хоть LCC это полностью ANSI C компилятор... но там есть скрытые... новые возможности вклюячая этот изврат с вирт функциями ... который не поддаётся объяснению =)... так что кто не понял почему иеноо так... то всё ок.