Объектно ориентированное программирование

Тема в разделе "WASM.WIN32", создана пользователем EvilsInterrupt, 16 ноя 2004.

  1. NeuronViking

    NeuronViking New Member

    Публикаций:
    0
    Регистрация:
    29 окт 2004
    Сообщения:
    476
    Адрес:
    где-то в Сиднее
    это в школе тебя учили ;) а в институте учишься сам....
     
  2. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    leo

    А еще можно заглянуть в исходники используемого компилятора.



    Или в исходники системных библиотек, ежели продукт в Enterprise-комплектации. Для Борланда это ...\Source\Rtl\Sys\... . Там даже комментарии есть :)



    S_T_A_S_

    Гы, да и кодогенератор у них практически один, не удивительно, что Borland забило на разработку компилеров %)



    Ваши данные несколько устарели. Все прогрессивное человечество уже затаило дыхание, ожидая выхода Delphi 2005 :) Вот в соседнем треде все дот-нет да дот-нет - а нифига! Win32 в исполнении Борланда наносит ответный удар.
     
  3. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    CyberManiac

    Почему-то сразу ассоциация со словом "конвульсия" возникла. :)
     
  4. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    const int * p1 = new int[10];

    int * const p2 = new int[10];

    При этом p1 - указатель на постоянный объект, то есть нельзя (запрещает компилятор) писать *p1=1; Тем не менее, компилятор не будет противиться строке *((int*)p1)=1; При указанной инициализации это не вызовет ошибок при исполнении, так как operator new () вообще не знает, что собираются делать с выделенной памятью - так что выделяет память на read/write. (Впрочем, выделять память только на чтение вряд ли целесообразно). const type* - указатели используется в контекстах: const char* func1(void) - означает, что не стоит модифицировать возвращаемое значение; void func2(const char*a) - означает, что функция не должна модифицировать переданный аргумент. Хотя если очень хочется, то это можно изменить. Хотя обычно, если указывается const - значит, это зачем-нибудь нужно. По поводу взаимосвязи const* со средствами ОС: нет никакой связи! Можно брать const- и не const-указатели на read-only область - при этом возникнут проблемы при записи; можно брать const- и не const-указатели на read/write область - не будет никаких проблем. Слово const можно рассматривать только как подсказку, которую можно игнорировать.

    Второй случай int*const p1=new int[10] означает, что запросто можно делать следующее:

    int a=*p1;*p1=1;int*a1=p1; но нельзя p1=b1; Хотя и в этом случае можно сказать (int*)p1=b1;
     
  5. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    CyberManiac >




    Что-то мне подсказывает, что последняя дельфи ничего не сможет откомпилировать, если нет csc.exe и al.exe =)
     
  6. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Все выше написанные мною вопросы разрешены, но на подходе новый:

    Напишем код:

    Class A

    {

    public:

    void setVariable(int Var){variable = var;}

    private:

    int variable;

    }



    когда в:

    int main()

    {

    A a1;

    A a2;

    }



    то в стеке будут созданы одна группа на 4 байта для а1 и вторая группа тоже из 4 байтов для а2.



    А в секции кода насколько я полагаю будет код метода setVariable берущего на себя скрытый указатель(так называемый this) на объект а1 или а2, в зависимости от ситуации.



    Так как же мне просмотреть в памяти реализацию и нахождение этого метода в памяти?
     
  7. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    ДЛя visual c++ v6.0!
     
  8. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    EvilsInterrupt

    setVariable в программе может вообще не оказаться, так как этот метод нигде не вызывается, а очень хороший компилятор в секцию кода один ret запишет ;)
     
  9. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Ладно. А так:

    int main()

    {

    A a1;

    A a2;

    a1.setVariable(2);

    return 0;

    }

    Как тута, т.е. как в файле или в адрессном пространстве найти этот метод?
     
  10. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    EvilsInterrupt

    Смотришь во что компилируется a1.setVariable(2) и в команде call как раз и будет написан адрес метода. Для вызова виртуальных методов будет написано что-то типа:
    Код (Text):
    1. mov reg,[this]; указатель на таблицу виртуальных функций
    2. call [reg+XX];XX - смещение адреса метода в таблице


    Тут, чтобы узнать реальный адрес, потребуется заглянуть в отладчик. А вообще если интересует как это все реализуется, включи генерацию листинга и посмотри. Только оптимизацию не забудь отключить, а то будет тяжело разбираться.
     
  11. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Black_mirror

    команде call как раз и будет написан

    Imho хороший компилятор метод, подобный указанному, превратит в inline.
     
  12. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    q_q

    Ну тогда только листинг смотреть. Потому что иначе мы даже не сможем узнать о наличии такого метода, а будем думать что variable объявлена как public, или вообще локальный int 8)
     
  13. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    EvilsInterrupt

    > "как в файле или в адрессном пространстве найти этот метод?"

    Если кратко: то в данном случае - также как бы ты искал обычную функцию - в отладчике или по листингу (а если ты в своей проге копаешься, то можешь в MessageBox вывести адрес своего метода).



    Лирическое отступление:

    Отличие вызова невиртуального метода от вызова обычной функции в том, что в метод неявно передается дополнительный параметр - указатель на экземпляр класса. С тонкостями СИ я не знаком, но дельфах по умолчанию используется тип вызова register (аналог сишного fastcall) с последовательностью передачи параметров EAX,EDX,ECX. Поэтому если бы setVariable была бы обычной функцией, то мы имели бы
    Код (Text):
    1. mov eax,2
    2. call rel32 <font color="gray];= call setVariable, rel32 - смещение setVariable относительно инструкции, следующей за call </font><!--color-->
    а для метода будем иметь
    Код (Text):
    1. mov eax,[xxxxxxxx] <font color="gray];= mov eax,a1</font><!--color-->
    2. mov edx,2
    3. call rel32
    Если метод виртуальный, как уже было сказано, он вызывается через VMT. Указатель на VMT - это первые 4 байта экземпляра класса. Продолжая дельфийский пример получим:
    Код (Text):
    1. mov eax,[xxxxxxxx] <font color="gray];= mov eax,a1</font><!--color-->
    2. mov edx,2
    3. mov ecx,[eax]   <font color="gray];указатель на VMT</font><!--color-->
    4. call [ecx+disp] <font color="gray];disp - смещение указателя на наш метод в VMT</font><!--color-->
    И еще замечание: в дельфах можно легко получить адрес на нужный метод, если объявить его опубликованным (published). Наверняка что-то подобное есть и в СИ (по крайней мере если класс наследуется от базового предка, на котором строятся визуальные компоненты). В частности программка DeDe дельфийские проги раскладывает по полочками с именами опубликованных методов - очень удобно.
     
  14. ozzman

    ozzman New Member

    Публикаций:
    0
    Регистрация:
    22 янв 2004
    Сообщения:
    56
    >Отличие вызова невиртуального метода от вызова обычной >функции в том, что в метод неявно передается >дополнительный параметр - указатель на экземпляр класса. >С тонкостями СИ я не знаком

    В C++ функции класса передается указатель на класс(this) в регистре ecx.
     
  15. ozzman

    ozzman New Member

    Публикаций:
    0
    Регистрация:
    22 янв 2004
    Сообщения:
    56
    >указатель на класс

    на объект класса, если быть точным
     
  16. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Точнее, ozzman, еще точнее - на экземпляр.
     
  17. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Господа, спасибо.



    Вот еще вопрос:

    Запись на си

    int a;

    int * b = &a;

    можно представить ввиде:

    a dd 0

    mov esi,offset a



    А если написать так:

    int a;

    int & ra = a;



    то как это можно представить?
     
  18. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    EvilsInterrupt

    Господа конечно рады помочь, но мне думается такие "вопросы" проще проверить самому, чем полдня ждать ответа. Пишешь тестовую программку, ставишь бряк в нужной точке и смотришь что получилось: или в интегрированном отладчике или в OllyDbg, или в каком другом. Для внешнего отладчика бряк создается ассемблерной вставочкой с int3 или db CCh. Просто, быстро и элемент исследования - может чего интересного обнаружишь и поделишься с мировой общественностью.
     
  19. infern0

    infern0 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2003
    Сообщения:
    811
    Адрес:
    Russia


    это вообще не должно компилится. IMO будет ругаться на lvalue, ну должен по крайней мере...
     
  20. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    infern0

    Неправда. В C++ есть такой тип как ссылка.



    EvilsInterrupt

    На уровне ассемблера код для ссылки будет аналогичен коду для указателя.