| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Хорошее или нет использование extern? |
| Автор: jonie 10.6.2009, 22:26 |
| Недавно производил небольшой рефакторинг одного солюшена. В нем в каждом проекте были скопипащены одни и теже файлы логгера, которые отличались только именем файла логгера, зашитого "рядом" через define (да, я бы тоже того кто делал убил бы, чтобы Земля не мучалась)... Итогово у меня получилось примерно такое: я сделал common.lib с классом логгера, который подключил к каждому проекту. В common.lib мною был определен extern tstring LOG_NAME (бывший дефайн). /* я не сделал передачу имени в конструктор, т.к. логгер оформлен как синглетон, и где его первое использование будет в проекте сказать нельзя */ в кажом проекте, куда включен common.lib мною был прошит tstring LOG_NAME, чтобы логгер нашел его. Считается ли это ужасом? Выносить логгер в динамическую либу запрещено. |
| Автор: azesmcar 11.6.2009, 00:58 |
| jonie Ничего плохого не вижу, extern и существует для подобных ситуаций. Вообще, для того чтобы говорить о том что какая либо конструкция - зло, надо иметь достаточно оснований. Тут я вообще оснований не вижу. Возможно если подумать, теоретически можно придумать решение и покрасивее, но зла я в этом решении однозначно не вижу. мое лично мнение |
| Автор: Earnest 11.6.2009, 08:10 |
| Когда имеешь дело со старым плохим кодом, который нужно использовать как есть, ничто ужасом не считается. Насчет практических соображений. В данном случае лучше глобальную переменную заменить парой: статическая переменная, видимая только в контексте библиотеки-логгера (пишу статическая, хотя она может продолжать оставаться глобальной, но не выходить за пределы библиотеки) + функция для ее установки, типа SetLogContext. Чем это лучше: во-первых, все безобразие скрывается (чем локализованнее ужас, тем он менее ужасен), во-вторых, при поддержке и изменениях проще справиться с функцией (найти все вхождения). Для этого ее имя можно сделать подлиннее... |
| Автор: xvr 11.6.2009, 11:46 | ||||
Не сработает - Logger оформлен как Singleton, поэтому невозможно предсказать что произойдет раньше - создасться собственно Logger (который подхватит имя лог файла), или вызовут функцию SetLogContext (которое это имя должна установить). 2 jonie У меня был аналогичный модуль (логер), и у него была аналогичная переменная (имя компоненты) и она задавалась так же, как у тебя. Видимо в этом есть какая то сермяжная правда PS. Только я ее задание завернул в дефайн, что бы не светить наружу детали реализации. Вот так
В принципе имя файла для лога можно выводить автоматом из имени исполняемого модуля (или из имени exe+имя dll - для dll) |
| Автор: xvr 11.6.2009, 13:27 | ||||
И как? Особенно если учесть, что логгер может быть вызван из конструкторов глобальных статических объектов. И заранее неизвестно где и сколько таких объектов будет. |
| Автор: xvr 11.6.2009, 13:51 | ||
| Забыл добавить. Все же одно отличие в моей реализации было - я использовал для задания имени модуля не string а char []
|
| Автор: Earnest 11.6.2009, 15:32 |
| Делов-то. Например, обернуть функцию вызова логгера другой, в которую включить вызов устновки имени. Это если действительно логгер может инициализировать не в коде. |
| Автор: ДокторТуамОсес 11.6.2009, 15:43 | ||
Ничего не понял. А так хотелось бы тоже понять о чём речь. Чувствую, что речь идёт о чём-то интересном. Не могли бы Вы сказать тоже самое но технически граммотным языком? |
| Автор: jonie 11.6.2009, 16:05 | ||
адаптер? дело-то конечно, хорошее и правильное, но там есть функции с переменным аргументов, и с ними будут проблемы при вызове исходного логгера. xvr в моей реализации также невозможно чтобы логгер был инициализирован, а tstring нет. Любой вызов логгера, который использует tstring вызовет её конструктор, разве нет? |
| Автор: xvr 11.6.2009, 17:32 | ||||
Нет. Если tstring физически не помещен в класс логера (а он туда не может быть помещен, т.к. описывается отдельно в каком то файле), то он будет статическим объектом и его конструктор будет вызван вместе со всеми конструкторами других статических объектов. Если другой статический объект создасться раньше, и из своего конструктора позовет логер, то логер будет читать непроинициализированную tstring Добавлено через 3 минуты и 8 секунд
Эту функцию придется где то расположить и написать. Чем (с точки зрения применения) это будет отличаться от макроса HR_MODULE, который будет так же расположен в том же самом месте? |
| Автор: Fazil6 12.6.2009, 10:11 | ||||
сказали же, обеспечить инициализацию tstring - как два пальца об асфальт. Заменяешь эту переменную функцией и все. Добавлено @ 10:15
ну хотябы областью видимости... |
| Автор: xvr 12.6.2009, 12:04 | ||||||||
Ну это не совсем 'инициализация tstring', но вполне нормальный вариант.
Так что нельзя считать, что функция лучше Кстати, имя файла для логера (точнее имя модуля, имя файла должно выводится из него) вообще можно задать макросом с командной строки компилятору (через -D). Такое решение совершенно прозрачно для программы в целом, но добавляет лишний шаг в настройку компиляции (что тоже не фонтан |
| Автор: andrew_121 12.6.2009, 12:35 | ||
Думаю могли бы. Но здесь не зазубры и ботаники. К Вашему сведению, слово граммотным, пишется с одним м |