Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.

Реклама



**Как получить V.I.P** (Перейти)
Чтобы заказать рекламу на Pro-Pawn.Ru, обращайтесь в Skype.
Баннерная реклама 100руб/мес, Текстовая 50руб/мес.
Показано с 1 по 10 из 10
  1. #1
    Аватар для VVWVV
    Проверенный

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    560
    Репутация:
    259 ±

    Перегрузка операторов

    Всем привет!

    В этом уроке я расскажу о перегрузке операторов.

    Введение
    В Pawn, как и в языке C++, присутствует перегрузка операторов. Она используется для изменения возвращаемого значения при какой-либо операции. Таким образом, она делает код более компактным, ведь при ином случае необходимо использовать обычные функции.

    Однако перегруженный оператор влияет на скорость работы кода. Следовательно, нельзя говорить о том, что это самый быстрый способ для решения какой-либо задачи.

    Ко всему прочему, имеет ряд ограничений. Например, вы не можете использовать оператор & для того, чтобы узнать адрес переменной. Кроме того, вы не можете использовать массивы/строки в аргументах. Хотя на этот счёт существует оператор emit, с помощью которого можно что-то сделать.

    Поэтому следует всегда помнить, что перегрузка операторов - это всего лишь удобный способ вызова какой-либо функции.

    Принцип работы
    Синтаксис перегрузки операторов очень прост: необходимо создать функцию, указать тег возвращаемого значения, а в самом названии указать ключевое слово operator и сам оператор. В круглых скобках необходимо указать заготовленные аргументы, иначе компилятор выдаст ошибку.

    Пример перегрузки оператора:
    PHP код:
    stock
        SomeTag
    :operator*(SomeTag:multiplicandsSomeTag:multiplier)
    {
        return 
    SomeTag:((multiplicands multiplier) + SomeTag:2);




    Однако, как говорилось выше, имеется ряд ограничений:
    1. Нельзя использовать оператор &, а также массивы в аргументах к оператору.
    2. Ограниченное число операторов. Таким образом, вы не сможете перегрузить большую часть операторов.
      Операторы не попавшие под ограничение:
      • Арифметические операторы ("=", "+" (сложение), "-" (вычитание), "+" (унарный плюс), "-" (унарный минус), "*", "/", "%", "++"(префиксный/постфиксный), "--" (префиксный/постфиксный)).
      • Операторы сравнения ("==", "!=", ">", "<", ">=", "<=").
      • Оператор логического НЕ ("!").


    Если говорить о составных операторах, то они работают так, как и перегруженные. Например, у нас есть перегруженный +, то оператор += будет работать так, как и оператор + и т.д.




    Для перегрузки оператора необходимо также знать его определение. Ниже приведена таблица с определениями операторов:
     Определения операторов
    Оператор Определение
    Присваивание
    PHP код:
    SomeTag:operator=(SomeTag:a
    Сложение
    PHP код:
    SomeTag:operator+(SomeTag:aSomeTag:b
    Вычитание
    PHP код:
    SomeTag:operator-(SomeTag:aSomeTag:b
    Унарный плюс
    PHP код:
    SomeTag:operator+(SomeTag:a
    Унарный минус
    PHP код:
    SomeTag:operator-(SomeTag:a
    Умножение
    PHP код:
    SomeTag:operator*(SomeTag:aSomeTag:b
    Деление
    PHP код:
    SomeTag:operator/(SomeTag:aSomeTag:b
    Остаток от деления
    PHP код:
    SomeTag:operator%(SomeTag:aSomeTag:b
    Инкремент (префиксный/постфиксный)
    PHP код:
    SomeTag:operator++(SomeTag:a
    Декремент (префиксный/постфиксный)
    PHP код:
    SomeTag:operator--(SomeTag:a
    Равенство
    PHP код:
    bool:operator==(SomeTag:aSomeTag:b
    Неравенство
    PHP код:
    bool:operator!=(SomeTag:aSomeTag:b
    Больше
    PHP код:
    bool:operator>(SomeTag:aSomeTag:b
    Меньше
    PHP код:
    bool:operator<(SomeTag:aSomeTag:b
    Больше или равно
    PHP код:
    bool:operator>=(SomeTag:aSomeTag:b
    Меньше или равно
    PHP код:
    bool:operator<=(SomeTag:aSomeTag:b
    Логическое отрицание, НЕ
    PHP код:
    bool:operator!(SomeTag:a





    Следует помнить, что для каждого тега необходимо использовать свою функцию. Таким образом, у вас не получится сделать так:
    PHP код:
    stock // Ошибочный код
        
    SomeTag:operator+(SomeTag:a, {Float,bool}:b)
    {
        return 
    SomeTag:(_:_:b);

    Для этого необходимо создать две функции:
    PHP код:
    stock
        SomeTag
    :operator+(SomeTag:aFloat:b)
    {
        return 
    SomeTag:(_:_:b);
    }

    stock
        SomeTag
    :operator+(SomeTag:abool:b)
    {
        return 
    SomeTag:(_:_:b);


    Скорость
    Перегруженный оператор влияет на скорость выполнения кода. Это происходит из-за того, что вы создаёте функцию, а также вызываете её. Поэтому рекомендую писать более-менее быстрый код в этих функциях.

    Читал комментарии некоторых пользователей, где они говорил, что выражение с перегруженным оператором быстрее, чем вызов нативной функции. Поэтому я решил аргументировать свой ответ. Приведу ассемблерный листинг (с использованием оператора):
     Aссемблерный листинг

    PHP код:
        proc    operator+(Float:,_:)
        ; 
    line 79
        
    break    ; c
        
    ;$lcl oper2 10
        
    ;$lcl oper1 c
        
    line 79
        
    break    ; 10
        load
    .s.pri 10
        push
    .pri
        
    ;$par
        push
    .c 4
        sysreq
    .c 0    float
        stack 8
        push
    .pri
        
    ;$par
        load
    .s.pri c
        push
    .pri
        
    ;$par
        push
    .c 8
        sysreq
    .c 1    floatadd
        stack c
        retn

        proc    
    main
        
    line 6
        
    break    ; 68
        
    line 7
        
    break    ; 6c
        
    ;$lcl a fffffffc
        stack fffffffc
        zero
    .pri
        stor
    .s.pri fffffffc
        
    ;$exp
        
    line 8
        
    break    ; 84
        load
    .s.pri fffffffc
        
    const.alt 7
        push
    .alt
        push
    .pri
        
    ;$par
        push
    .c 8
        call .40000004
    +0    operator+(Float:,_:)
        
    stor.s.pri fffffffc
        
    ;$exp
        stack 4
        zero
    .pri
        retn 


    Если же говорить лишь об использовании нативной функции, то вот листинг:
     Aссемблерный листинг

    PHP код:
        proc    main
        
    line 6
        
    break    ; c
        
    line 7
        
    break    ; 10
        
    ;$lcl a fffffffc
        stack fffffffc
        zero
    .pri
        stor
    .s.pri fffffffc
        
    ;$exp
        
    line 8
        
    break    ; 28
        
    const.pri 40e00000
        push
    .pri
        
    ;$par
        load
    .s.pri fffffffc
        push
    .pri
        
    ;$par
        push
    .c 8
        sysreq
    .c 0    floatadd
        stack c
        stor
    .s.pri fffffffc
        
    ;$exp
        stack 4
        zero
    .pri
        retn 


    Как мы видим, в первом листинге исполняемых инструкций больше, чем во втором. Кроме того, в первом листинге вызываются 3 функции, во втором же всего одна.

    Вывод
    В Pawn перегрузка операторов является очень закрытой. Как уже было сказано выше: многие операторы нельзя перегрузить. Кроме того, очень много ограничений в аргументах функции-перегрузки: нельзя использовать массивы, нельзя использовать оператор & для получения адреса и т.п.

    Автор: VVWVV
    Исключительно для pro-pawn.ru

    Копирование данной статьи на других ресурсах без разрешения автора запрещено!
    Последний раз редактировалось VVWVV; 04.01.2017 в 22:09.

  2. #2
    Аватар для DeimoS
    Модератор?

    Статус
    Онлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    3,532
    Репутация:
    1388 ±
    Цитата Сообщение от VVWVV Посмотреть сообщение
    она делает код более меньше
    "более компактным" звучало бы лучше =)
    Связаться со мной можно в личных сообщениях этой группы

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  3. #3
    Аватар для VVWVV
    Проверенный

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    560
    Репутация:
    259 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    "более компактным" звучало бы лучше =)
    Да. Исправил.

  4. #4
    Аватар для KrutoyKrosch
    Пользователь

    Статус
    Оффлайн
    Регистрация
    26.02.2016
    Сообщений
    272
    Репутация:
    7 ±


    Зачем такая эксклюзивность?

  5. #5
    Аватар для VVWVV
    Проверенный

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    560
    Репутация:
    259 ±
    Цитата Сообщение от KrutoyKrosch Посмотреть сообщение


    Зачем такая эксклюзивность?
    Для развития данного форума. Например, для привлечения новых посетителей и т.п.

  6. #6
    Аватар для $continue$
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.08.2014
    Адрес
    г. Киров (aka Вятка)
    Сообщений
    1,359
    Репутация:
    241 ±
    В реальных условиях ползи от перегрузки в Pawn - мало. Например: оператор "==" не перегрузить для проверки строк (используя strcmp), т.к никак не передашь в функцию массив. Очень урезанная перегрузка. Технического применения ее почти нет.

    И кстати в Cях нельзя же перегрузить операторы.
    Последний раз редактировалось $continue$; 03.01.2017 в 21:56.
    Value your freedom or you will lose it, teaches history. "Don't bother us with politics," respond those who don't want to learn. (c) Richard Stallman

  7. #7
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    928
    Репутация:
    645 ±
    Цитата Сообщение от $continue$ Посмотреть сообщение
    И кстати в Cях нельзя же перегрузить операторы.
    Там оно и не нужно. А в Pawn они есть исключительно из-за отсутствия типов и необходимости поддержки Float чисел.

  8. #8
    Аватар для Daniel_Cortez
    new fuck_logic[0] = EOS;

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    1,567
    Репутация:
    2076 ±
    Цитата Сообщение от $continue$ Посмотреть сообщение
    В реальных условиях ползи от перегрузки в Pawn - мало. Например: оператор "==" не перегрузить для проверки строк (используя strcmp), т.к никак не передашь в функцию массив. Очень урезанная перегрузка. Технического применения ее почти нет.

    И кстати в Cях нельзя же перегрузить операторы.
    В исходниках Pawn частично реализована "привязка" к строковой библиотеке BString. И, я так понимаю, единственное, что удерживает её от попадания в релиз - условия лицензии (двойное лицензирование под GPL и 3-пунктовой BSDL), накладывающие дополнительные ограничения на релиз в объектной форме. Тем не менее, можно доработать это поделие до плагина к SA-MP.
    Индивидуально в PM и Skype по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).
    SA-MP 0.4 is a lie

  9. #9
    Аватар для $continue$
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.08.2014
    Адрес
    г. Киров (aka Вятка)
    Сообщений
    1,359
    Репутация:
    241 ±
    Я к тому, что у автора в шапке темы "C/C++"
    Цитата Сообщение от ziggi Посмотреть сообщение
    Там оно и не нужно. А в Pawn они есть исключительно из-за отсутствия типов и необходимости поддержки Float чисел.
    Value your freedom or you will lose it, teaches history. "Don't bother us with politics," respond those who don't want to learn. (c) Richard Stallman

  10. #10
    Аватар для VVWVV
    Проверенный

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    560
    Репутация:
    259 ±
    Цитата Сообщение от $continue$ Посмотреть сообщение
    В реальных условиях ползи от перегрузки в Pawn - мало. Например: оператор "==" не перегрузить для проверки строк (используя strcmp), т.к никак не передашь в функцию массив. Очень урезанная перегрузка. Технического применения ее почти нет.

    И кстати в Cях нельзя же перегрузить операторы.
    Да. Исправил.

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •