Русское сообщество по скриптингу

Как перегрузить оператор присваивания?

Все вопросы по скриптингу для Metamod, помощь в редактировании плагинов.
Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы, касающие только скриптинга для
Metamod.


Правила при создании новой темы:
1. При вставке кода плагина необходимо использовать тег [pawn], в противном случае, если тег [pawn] не отображает ваш код, можно использовать тег [code].
2. Любые изображения должны быть загружены, как вложения к вашему сообщению.
3. При описании проблемы или запросе на помощь в редактировании плагина обязательно выкладывайте исходник плагина.

Как перегрузить оператор присваивания?

Сообщение Chuvi » 11 ноя 2013, 21:05

Ситуация:
У меня есть класс
Код: Выделить всё

template 
<typename T>
class CSymb
{
public:
 T Get(){return Symb}
private:
T Symb;
 


Подскажите, пожалуйста, как мне перегрузить оператор = чтобы можно было делать такие финтоплясы:
Код: Выделить всё

void SomeFunc
()
{
CSymb<int*> Symb;//По ряду причин здесь всегда указатель на какой-либо тип.
int SomeAnotherVar=Symb;
SomeAnotherVar++;
Symb=SomeAnotherVar;
}

 
Плагинами на заказ не занимаюсь.
Своих дел хватает.
Аватара пользователя
Chuvi
Модератор
 
Сообщения: 2253
Зарегистрирован: 24 ноя 2011, 08:03
Благодарил (а): 127 раз.
Поблагодарили: 562 раз.

Re: Как перегрузить оператор присваивания?

Сообщение 6a6kin » 11 ноя 2013, 23:58

Код: Выделить всё
template <typename T>
class CSymb
{
public:
  T Get() { return Symb; }
  operator int() { return (int)Symb; }
  CSymb &operator=(int x) { Symb = (T)x; return *this; }
private:
  T Symb;


По-моему так.
На заказ не пишу.
Аватара пользователя
6a6kin
Скриптер
 
Сообщения: 332
Зарегистрирован: 09 мар 2010, 16:40
Благодарил (а): 38 раз.
Поблагодарили: 278 раз.

Re: Как перегрузить оператор присваивания?

Сообщение Chuvi » 12 ноя 2013, 00:59

6a6kin, вроде получилось, только почему надо возвращать this?
Добавил вложения, чтобы было понятно, что я вообще пытаюсь соорудить.

Кстати, как можно вызвать класс как функцию?
А то вызов функции-класса (я хз как это грамотно обозвать) CFuncHook и CFunc сейчас выглядит так
Код: Выделить всё
SomeHookedFunc()(param1, param2)

В общем, есть ли возможность избавиться от первой пары скобок?

(Я не удивлюсь, если у меня там вообще костыль на костыле сидит. Как-никак первый раз сделал что-то с использованием шаблонов :))
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Плагинами на заказ не занимаюсь.
Своих дел хватает.
Аватара пользователя
Chuvi
Модератор
 
Сообщения: 2253
Зарегистрирован: 24 ноя 2011, 08:03
Благодарил (а): 127 раз.
Поблагодарили: 562 раз.

Re: Как перегрузить оператор присваивания?

Сообщение 6a6kin » 12 ноя 2013, 01:09

*this надо возвращать, потому что можно написать a = b = c;

Есть такое понятие, как функтор. Ещё иногда видел название функционал. Перегружается operator() и можно вызывать как функцию. У тебя так и есть, только добавь параметры и вызывай Call(param1, param2)
На заказ не пишу.
Аватара пользователя
6a6kin
Скриптер
 
Сообщения: 332
Зарегистрирован: 09 мар 2010, 16:40
Благодарил (а): 38 раз.
Поблагодарили: 278 раз.

Re: Как перегрузить оператор присваивания?

Сообщение Chuvi » 12 ноя 2013, 01:15

6a6kin писал(а):*this надо возвращать, потому что можно написать a = b = c;


Сомневаюсь, что возникнет необходимость прямого присваивания классов в данном случае.
То есть, как я понял, this нужно возвращать для того, чтобы можно было сделать так:
Код: Выделить всё
CSymb<cl_enginefuncs_t> cl_enginefuncs;
CSymb<engine_studio_api_s> IEngineStudio;
cl_enginefuncs=IEngineStudio

Думаю, понимаешь, что в данном контексте такая ситуация весьма абсурдна.
Несколько позабавил такой момент.
cl_enginestudio. - работаем с классом
cl_enginestudio->=работаем со структурой cl_enginestudio_t.

6a6kin писал(а):Есть такое понятие, как функтор. Ещё иногда видел название функционал. Перегружается operator() и можно вызывать как функцию. У тебя так и есть, только добавь параметры и вызывай Call(param1, param2)

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

Кстати, если не заметил, это engFunc из FloodBlocker-a. Только немного переделанный. (нифига се немного...)
Плагинами на заказ не занимаюсь.
Своих дел хватает.
Аватара пользователя
Chuvi
Модератор
 
Сообщения: 2253
Зарегистрирован: 24 ноя 2011, 08:03
Благодарил (а): 127 раз.
Поблагодарили: 562 раз.

Re: Как перегрузить оператор присваивания?

Сообщение 6a6kin » 12 ноя 2013, 01:35

Там пропущено что-то в коде?
Код: Выделить всё
CSymb<cl_enginefuncs_t> cl_enginefuncs;
CSymb<engine_studio_api_s> IEngineStudio;
cl_enginefuncs = IEngineStudio = 0x00ffffff;

Я так понимаю, что что-то типа этого должно было быть.
Ну вот для такого и нужно. Это стандарт. Так надо делать, так как всё равно нужно что-то возвращать.

Тогда пихай аргументы в структуру переменной длины.
Типа этого:
Код: Выделить всё
struct args
{
  int size;
  char content[1];
};

А её потом сразу в стек. Либо пихай в контейнер по одному параметру и передавай контейнер.

// Code derived from code from David Anderson
// You're going to help us, Mr. Anderson whether you want to or not. (c)

Офк, заметил, тем более, что коммент остался мой)

Я бы, если нужно было бы улучшить (а там нужно и я хотел), шаблонами делать не стал бы. Ну их нафиг. Это не тот случай. Шаблоны нужны для контейнерных классов, которые хранят вполне определённые объекты.

С++, между прочим, мультипарадигменный язык с уклоном в low-level. Это значит, что там можно сочетать ООП и процедурное и обобщённое программирование.
А ООП создан был для решения проблемы сложности ПО. Чтобы БОЛЬШИЕ программы было легко поддерживать и расширять. Короче, я не советую тут шаблоны пихать.
На заказ не пишу.
Аватара пользователя
6a6kin
Скриптер
 
Сообщения: 332
Зарегистрирован: 09 мар 2010, 16:40
Благодарил (а): 38 раз.
Поблагодарили: 278 раз.

Re: Как перегрузить оператор присваивания?

Сообщение Chuvi » 12 ноя 2013, 01:53

6a6kin писал(а):Там пропущено что-то в коде?
Код: Выделить всё
CSymb<cl_enginefuncs_t> cl_enginefuncs;
CSymb<engine_studio_api_s> IEngineStudio;
cl_enginefuncs = IEngineStudio = 0x00ffffff;

Я так понимаю, что что-то типа этого должно было быть.
Ну вот для такого и нужно. Это стандарт. Так надо делать, так как всё равно нужно что-то возвращать.

Эээ.. :crazy:. Не, в данном контексте так делать, как-раз таки не надо. В каких нибудь других случаях - да, но не здесь. Не думаю, что приравнивать 2 совершенно разные структуры - хорошая идея. И тем более приравнивать их какому-то значению.


6a6kin писал(а):Тогда пихай аргументы в структуру переменной длины.
Типа этого:
Код: Выделить всё
struct args
{
  int size;
  char content[1];
};

А её потом сразу в стек. Либо пихай в контейнер по одному параметру и передавай контейнер.

Так всё равно подсказок не будет. Ладно, оставим пока две пары скобок.

6a6kin писал(а):Я бы, если нужно было бы улучшить (а там нужно и я хотел), шаблонами делать не стал бы. Ну их нафиг. Это не тот случай. Шаблоны нужны для контейнерных классов, которые хранят вполне определённые объекты.


Да меня один товарищ, который тут переодически обитает, достал на тему необходимости перетащить функции хука в класс. 2 месяца пытался это сделать, но так ничего и не сделал. :)
(Да и заодно таки сам решил шаблоны осилить)
Плагинами на заказ не занимаюсь.
Своих дел хватает.
Аватара пользователя
Chuvi
Модератор
 
Сообщения: 2253
Зарегистрирован: 24 ноя 2011, 08:03
Благодарил (а): 127 раз.
Поблагодарили: 562 раз.

Re: Как перегрузить оператор присваивания?

Сообщение 6a6kin » 12 ноя 2013, 02:10

Да меня один товарищ, который тут переодически обитает, достал на тему необходимости перетащить функции хука в класс.

Тут всё дело в том, что хук вещь сложная и не однотипная. Т.е. два хука могут сильно отличаться друг от друга.
Тебе же не нужно строить фреймворк для перехвата, вроде орфея, синхронизируя разные плагины.
На заказ не пишу.
Аватара пользователя
6a6kin
Скриптер
 
Сообщения: 332
Зарегистрирован: 09 мар 2010, 16:40
Благодарил (а): 38 раз.
Поблагодарили: 278 раз.

Re: Как перегрузить оператор присваивания?

Сообщение 6a6kin » 12 ноя 2013, 13:42

В общем, можно сделать так. Написать утилиту или плагин к редактору\IDE, которая по какому-то простому представлению сгенерирует готовые функции.

Например, по такому представлению:
оригинальный прототип
сигнатура
маска
кол-во байт в сигнатуре
Код: Выделить всё
void IsSafeFileToDownload(const char *filename);
\x55\x8B\xEC\x56\x8B\x75\x08\x85\xF6\x57\x0F\x84\xCA\x01\x00\x00\x6A\x04\x68\x4C\x4B\xE6\x01\x56\xE8\xD3\x57\xF9\xFF\x83\xC4\x0C\x85\xC0\x75\x09\x5F\xB8\x01\x00\x00\x00\x5E\x5D\xC3
xxxxxxxxxxxx????xxx????xx????xxxxxxxxxxxxxxxx
45
На заказ не пишу.
Аватара пользователя
6a6kin
Скриптер
 
Сообщения: 332
Зарегистрирован: 09 мар 2010, 16:40
Благодарил (а): 38 раз.
Поблагодарили: 278 раз.

Re: Как перегрузить оператор присваивания?

Сообщение Chuvi » 12 ноя 2013, 18:49

6a6kin,
количество байт-то зачем? Почему нельзя использовать strlen маски?
А плагин такой уже есть. IDA SigMaker, вроде, называется.
Плагинами на заказ не занимаюсь.
Своих дел хватает.
Аватара пользователя
Chuvi
Модератор
 
Сообщения: 2253
Зарегистрирован: 24 ноя 2011, 08:03
Благодарил (а): 127 раз.
Поблагодарили: 562 раз.

След.

Вернуться в Скриптинг

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4