[c++] спецам define или типа того =)

Maurog

есть большой проект. в котором есть глобальная переменная типа
big_class globvar;
она явным образом используется во многих функциях
таким образом есть ограничение-в программе может быть только один элемент этого класса. иначе работать не будет.
решил я сделать поддержку неограниченного числа таких классов путем смены типа вот у этой переменной на указатель.
то есть возложим на эту переменную смысл быть "текущим объектом".
но тогда, надо все
globvar.method1(args)
globvar.method2(args)
globvar.method3(args)
заменить на
globvar->method1(args)
globvar->method2(args)
globvar->method3(args)
для этого я написал
#define globvar (*globavar)
замечу, что это даже помогло исправить строчки
extern big_class globvar; в других файлах
этот дефайн я вставил в один хедер, который присутствует во всех файлах.
однако возникла проблема-я не могу теперь изменить значение указателя big_class *globvar;
как это сделать?
может быть дефайн неудачный..
тогда придумайте другой )
то есть проблема такая: минимальными усилиями заменить точку на стрелочку -> и иметь возможность менять переменную globvar которая должна уже являться указателем big_class *.
исправлять точку на стрелочку во всех файлах ручками не принимаю.
критика в сторону неправильной реализации тоже не принимаю-я знаю, что это так, но времени нет переводить все в нормальный ООП. и стоить это будет увеличение и времени работы десятилетних алгоритмов и увеличение памяти, которой и так не хватает (2 Г сжирается легко)
надеюсь, вы сможете придумать интересные дефайны
то есть хочется иметь возможность вернуться к старому варианту путем стирания трех дефайнов..и к новому, с помощью ваших дефайнов
принимаются совершенно иные методы решения этой проблемы..когда имеется куча явных указания на глобальную переменную..и минимальными усилиями сделать поддержку большого числа таких классов
кстати дефайны типа
#define globvar. globvar->
были бы очень полезны но не работают ;(

a10063

исправлять точку на стрелочку во всех файлах ручками не принимаю.
может, тогда применить replace ко всем вхождениям globvar на (*globvar) во всех файлах автоматически?
дефайны же могут повлечь большие проблемы...
другой путь - менять класс big_class при некотором ограничении условий задачи

freezer

а почему нельзя делать: globavar=&globvar10; ?
Или иногда может хватить такого:
#ifdef globvar
#undef globvar
#endif
#define globvar globvar_big_class
и заменять им (но уже не в рантайме, а на этапе компиляции)

Maurog

реплейс-это то же самое, что ручками менять.
проект здоровый.
насчет изменения класса-я придумал только дописать к нему оператор копирования...типа
big_class h;
globvar = h;
копирование только копирует члены класса (указатели на другие объекты (но не сами объекты, которые стоят за этими указателями)....и просто инты и тд)
здесь учитываем, что полное копирование объекта сделать нереально...у него внутри столько барахла, что пипец памяти не хватит
таким образом текущий эелемент класса меняется путем копирования внутренних переменных.
если хочется выполнить функции (которые привязаны к глобальной переменной globvar ) над другим элементом класса, то можно сделать
big_class * j;
j= new big_class;
globvar = *j; // тут сработал оператор копирования
/*
делаем функции
*/
это как вариант
пс: вспомнил, что вариант не прокатит..в классе есть члены типа
drugoy_big_class f;
который копировать я задолбаюсь

Maurog

отмечу, что дефайн не повлек никаких абсолютно проблем..
проблема встала: изменить этот указатель в условиях данного дефайна.
пытался всякие #undef применить в месте, где хочу изменить указатель-ничего не получилось или хотел сделать
#define old_obj globvar
#define globvar (*globvar)
и использовать old_obj для доступа именно к указателю-ничего тоже не получилось...дефайны полностью раскрылись

a10063

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

a10063

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

Maurog

"можно сделать круче "
в этом вся и проблема

ppplva

А все таки, в чем проблема с заменой -> на . ?
Пара регэкспов сделает процентов 95%, остальное подскажет компилятор.
#define в данной ситуации, имхо, идеальное средство запутывания кода.
Как вариант, класс, который содержит указатель на big_class и перенаправляет туда все вызовы.

Maurog

слово "потом" тут неуместно, ибо сразу видно, что это криво...требуется к уже написанному проекту приляпать возможность работать с многими объектами типа big_class

a10063

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

rosali


для этого я написал
#define globvar (*globvar)
замечу, что это даже помогло исправить строчки
extern big_class globvar; в других файлах
этот дефайн я вставил в один хедер, который присутствует во всех файлах.
однако возникла проблема-я не могу теперь изменить значение указателя big_class *globvar;
как это сделать?

big_class * globvar;
void set_globvar(big_class * _globvar)
{
globvar = _globvar;
}
#define globvar (*globvar)

ppplva

Короче, если нужно сдать проект и забыть о нем навсегда - фигарь define смело
Хотя регэкспом все равно проще...

Maurog


А все таки, в чем проблема с заменой -> на . ?
Пара регэкспов сделает процентов 95%, остальное подскажет компилятор.
регекспы-ето перелопачивание кода в авто режиме..ето когда из файла a.cc делают файл a.cc_done, который перемещают потом по адресу a.cc, чтобы затереть предыдущий вариант..тут бегают по куче директориям, по куче файлам...короче тут похерить весь код мона, и вообще нету возможности так гонять файлы по директориям. вот если бы в дефайнах были регекспы, то я бы не волновался

#define в данной ситуации, имхо, идеальное средство запутывания кода.
как можно запутать код, если он многолетний и все привыкли делать globvar.method18(args) ? просто будут другие функции, которые подменяют текущий объект. другие разработчики писали и пишут код для одного элемента класса, а я расширяю возможности и делаю эти функции для многих классов.
я живу со многими классами, остальные прогеры живут с одним классом. и все довольны.

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

Maurog

Короче, если нужно сдать проект и забыть о нем навсегда - фигарь define смело
Хотя регэкспом все равно проще...
неее... мне с этим проектом годы работать..так что не покатит

rosali


А все таки, в чем проблема с заменой -> на . ?
Пара регэкспов сделает процентов 95%, остальное подскажет компилятор.
Если вместо замены "globvar." -> "globvar->" делать замену "globvar" -> "globvar" то 95% превратятся в 100%. Ну, понятно надо приписать
 
big_class * p_globvar;
big_class & globvar
{
return *p_globvar;
}

tokuchu

а если сделать вот так:
big_class *p_var;
#define globvar (*p_var)
и изменять потом p_var?

ppplva

регекспы-ето перелопачивание кода в авто режиме..ето когда из файла a.cc делают файл a.cc_done, который перемещают потом по адресу a.cc, чтобы затереть предыдущий вариант..тут бегают по куче директориям, по куче файлам...короче тут похерить весь код мона, и вообще нету возможности так гонять файлы по директориям. вот если бы в дефайнах были регекспы, то я бы не волновался
Боишься похерить - сделай бекап
Причем здесь процесс сборки ? Если в исходных файлах тупо заменить . на -> - неужели не будет работать ? Или нужные конструкции формируются уже после препроцессинга ?
define - тот же регэксп, только выполняется он во время каждой сборки, да возможностей у него поменьше (в данном контексте).

rosali

когда из файла a.cc делают файл a.cc_done, который перемещают потом по адресу a.cc, чтобы затереть предыдущий вариант..тут бегают по куче директориям, по куче файлам...
 find ./ -name *.cc | xargs sed -i ... 

Maurog

big_class * globvar;
void set_globvar(big_class * _globvar)
{
globvar = _globvar;
}
#define globvar (*globvar)
Это значит, что хедер #include "big_class.h" (который включается во все файлы) вставить _после_ моей фнукции, которая подменяет указатели (чтобы дейфайн там не сработал)
инклюд в середине файла-еще тот кайф )
но тогда мне придется в первой строчке этого файла писать
extern big_class * globvar;
чтобы все скомпилялось?
я в принципе не против этого даже..мне лишь бы чтобы скомпилялось
изменения минимальные:
1) в суперхедер вставляется мой супер дефайн
2) функция, которая меняет указатели должна быть перед вставкой этого хедера (таких функций вообще мало есть..и будет)

rosali

big_class *p_var;
Не p_var, а __very_unique_id_2873461398576

Maurog

зеленый, пагади
ты чо-то умное предложил
ща покумекаю)
здрямс, кстати

ppplva

это речь по ходу о синглтоне. но он нужен только для поддержания ооп. если с ним мона сделать - это значит, что и без него мона подменять этот злой указатель..а именно к этому и стремлюсь, а с этим синглтоном только культурность коду можно будет придать..короче не в нем дело.
Нет, не то. "Тонкий" объект, который втупую перенаправляет все вызовы исходному большому объекту (по указателю и умеет переключаться на другой большой объект (заменой указателя). Синтаксически совместимый с исходным объектом.
Хотя то, что предлагает , еще лучше. Вот здесь:

Maurog


find ./ -name *.cc | xargs sed -i ...
ты уверен, что я на солярке это сделаю?:)

tokuchu

ты чо-то умное предложил
То же, что и , но без функции.

rosali

Ладно, все забейте. С #define-ом идея тупизм в любом случае. Советую на первое апреля дописать в этот супер хедер такой супер define
 #define else 
вот смеху то будет

rosali

ты уверен, что я на солярке это сделаю?
Ну ты набери, а там посмотрим
 
find ./ -name *.cc | xargs sed -i s/globvar/globvar/g

ppplva

Супер! Это еще веселее, чем
#define i j  

rosali


"Тонкий" объект, который втупую перенаправляет все вызовы исходному большому объекту
Когда в классе big_class станут добавляться методы, предется их и в этот хелпер добавлять. Можно и устать

Maurog

такую херню в дефайн мона всунуть даже
нафиг регекспы?:)
я же грю-одним движением руки чтобы вернуться назад мона было

Maurog

этот тонкий объект надо будет перегружать дохера раз? (добавлять методы, который в исходном классе есть)всякие методы вставлять?
нафиг это чудо

Maurog

так что

find ./ -name *.cc | xargs sed -i s/globvar/globvar/g
идет лесом

Maurog

нееее
зеленый, это совсем разные методы)
ты не предлагал делать инклюд внутри кода и фиксировать порядок функций...
хотя, мож, я чо-то не понимаю...
в общем завтра додумаю все ето дело
спасибо всем за живую дискуссию
Оставить комментарий
Имя или ник:
Комментарий: