Заблокирован
|
|||||||||||
1 | |||||||||||
препроцессор с++02.09.2011, 19:59. Показов 5432. Ответов 47
Метки нет (Все метки)
Задача:
Сделать так, что бы при определённом условии класс "знал" что его тестируют в консоли, и выводил в неё всю необходимую служебную информацию. В режиме же реальной работы, даже сам код вывода данных в консоль не должен быть скомпилированным. Возникшая сложность: В случаи, если режим работы - тестирование классов, то требуется выполнить некоторую предварительную подготовку приложения к работе. Другими словами - запустить на выполнение некий набор функций. Вопрос: Можно ли так сделать, что бы в случае, если идентификатор (#define) определён - при компиляции будут запущены и выполнены некоторые дополнительные функции? Один из вариантов ответа: Ниже представлен полностью рабочий код. В нём мне удалось реализовать задачу, озвученную выше. Однако, удалось это сделать только при помощи глобального объекта. Меня же интересует, можно ли это сделать как нибудь так, что бы обойтись без глобальных объектов? А так же, к каким проблемам может привести ниже представленный код. Критика кода приветствуется.
Он объявляется, и определяется в глобальном пространстве. Код, выполняемый в его конструкторе - это и есть тот кусок кода, которые запустится в случае, если дефайн будит определён. 1. К каким проблемам могут привести макросы? 2. К каким проблемам может привести создание глобального объекта? 3. Есть ли другие способы добиться аналогичного эффекта, но при этом, вообще не создавая глобальных объектов? 4. Как сделать макросы кросс-платформенными? В частности, нужно избавиться от windows.h в случае, если компилируемый код - не под ос виндовс. Но тогда объект GlobalRun ругнется на незнание функций консоли... Добавлено через 11 минут /зы в строке 75 - опечатка
0
|
02.09.2011, 19:59 | |
Ответы с готовыми решениями:
47
препроцессор, #if Препроцессор Препроцессор С++Builder Препроцессор vs текст |
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
|
|
03.09.2011, 10:01 | 21 |
Может быть, шаблоны, специализация и принцип SFINAE "спасут отца русской демократии"?
И у Александреску, и в справочнике по шаблонам написаны compile-time функции с использованием шаблонов. Например, для того, чтобы в compile-time выяснить, есть ли в классе некий метод.
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
03.09.2011, 10:03 | 22 |
Только для шаблонных классов использовать можно, иначе всё равно ошибка компиляции будет.
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
03.09.2011, 14:55 | 25 |
А разве нет? Я сильно вопрос не изучал, могу и ошибаться. А зачем это вообще нужно без шаблонов? Ведь для известного типа и так интерфейс известен. Непонятно...
0
|
03.09.2011, 15:00 | 26 |
SFINAE можно применять не только к шаблонным типам. сам по себе SFINAE - шаблон.
а как я понял это - ты хотел сказать что SFINAE можно применять только к шаблонным типам. правильно? второе - SFINAE невозможно применить к не_специализированному_шаблону. а из этого следует, что в данном контексте, шаблон уже таковым не является. что равносильно не шаблонному типу.
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
03.09.2011, 15:04 | 27 |
Я имел в виду, что тип нужно передавать в качестве параметра шаблона.
Впрочем, мне эту идиому использовать пока не приходилось, поэтому я вообще не вкурсях.)
0
|
Заблокирован
|
||||||
03.09.2011, 15:28 [ТС] | 29 | |||||
Я хочу выполнить некие предварительные подготовки проекта к работе. Причем, что бы происходило это автоматически - достаточно подключить соответствующий инклуд.
То бишь, некий хэдер (плюс набор управляющих дефайнов) выступают в роли этакой стратегии компиляции. Однако, предварительная подготовка может потребовать запуска некого набора функций (например, настройка кодировки для консоли). Но нельзя запускать код на выполнение до точки входа в программу (до main() ) Обходной путь - создание глобальных объектов. Они при инициализации в глобальном пространстве могут запускать в своих конструкторах любые функции, и по сути эти функции выполнятся ещё до точки main() Меня интересует, если ли какой нибудь способ, что бы сделать тоже самое, но без глобал объектов? А так же, если для этой цели использовать глобальные объекты, не приведёт ли это к каким либо проблемам? Я слышал что-то типа того, что инициализация объекта в хэдере - это мина замедленного действия. Поэтому и обеспокоился. Ещё один способ запуска функции до точки main()
Профит: Построить указатель дешевле, чем сам объект. А функция, которая будит передана в конструктор указателя может быть самой обычной функцией. Таким образом, будит создан всего лишь один нигде не используемый глобальный указатель. Есть даже вероятность, что оптимизирующий компилятор и вовсе - выбросит этот момент инициализации из целевого кода, и тогда все подготовки пойдут прахом. Но... эксперимент показывает, что вроде бы пока все работает))
0
|
03.09.2011, 15:45 | 30 |
меньше не получилось
сейчас прочту... Добавлено через 8 минут нет. очень может. тут, GetInstance() - статический метод, а my1 - глобальная переменная? я ничего не напутал?
0
|
Заблокирован
|
|
03.09.2011, 16:05 [ТС] | 31 |
Типа да. my1 - это указатель. Дешевый в плане конструирования.
А вместо GetInstance() может быть любая функция, не обязательно классовый статик. Способ подготовиловки такой: в хэдере прописываются функции, которые потенциально могут понадобится. Дальше за дело принимается препроцессор - он выбирает нужную линию компиляции. На каждой такой линии инициализируется глобальный указатель, с помощью которого запускается нужный пакет "предварительных функций" Методы классов, и их аспективная начинка (логи всякие, внутренние проверки, и тп) - все это оборачивается в макросы типа TEST, что должно гарантировать: когда, какие, и при каких условиях методы будут скомпилированы, а какие - нет. Задача этих методов - инспектировать внутреннею работу класса, выявлять ошибки, которые невозможно выявить на этапе компиляции. Ошибки компиляции я предполагаю выявлять по методике Роббинсона (напоминает Александресску) - добавление в приватную зону методов, которые никогда не будут вызваны, а потому и скомпилированы, но будут ругаться на нарушения некоторых контрактов класса. Так же, в процессе разработки класса, я предполагаю разработку дополнительного класса, единственная задача которого - подвергнуть юнит-тестированию целевой класс. Все автоматические юнит-тесты должны произойти ещё до точки main() То бишь, создаётся глобальный указатель, который инициализируется статик-методом класса-тестера. Этот статик метод запускает пакет тестовых функций, которые должны охватить весь интерфейс тестируемого класса, ну и тп. Таким образом, инициализация указателя происходит в хедере, а не в файле спп. И этот момент идеи меня несколько смущает. Ну и напоследок, думаю неплохо было бы предусмотреть режим, когда юнит-тестам подвергается каждый только что созданный объект, с конкретным набором стартовых данных.
0
|
03.09.2011, 16:11 | 32 |
на самом деле, инициализация происходит при запуске приложения. загрузчик ОС, выполняет инициализацию данных располагающихся в секции .data исполняемого файла. это так, к сведению.
но потенциальную проблему я вижу в другом - стандарт не дает никаких гарантий на порядок инициализации/разрушения статических переменных, а следовательно, при их множественном кол-ве и взаимном использовании ожидайте UB.
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
03.09.2011, 16:18 | 33 |
Если GetInstance геттер синглтона, а указатель создаётся не в хэдэре, а в файле реализации, то проблем быть не должно.
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
03.09.2011, 16:46 | 35 |
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||||||
03.09.2011, 17:10 | 38 | |||||
При этом ошибка в Func2 будет обнаружена в любом случае.
0
|
Заблокирован
|
|
03.09.2011, 17:21 [ТС] | 39 |
геттер действительно синглтоновский, что до создания указателя...
Вся идея конструируется на том, что он инициализируется в хэдере. Очень не хочется плодить армию спп для поддержки тестов... Особенно, если речь идёт о тестировании шаблонных классов, которым спп не нужен в принципе.
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
03.09.2011, 17:32 | 40 |
С синглтоном может и с хэдэрами проблемы не будет. Но только при условии, что синглтон корректно реализован и все, кто от него зависят обращаются именно через геттер к нему. Ну и указатели лучше static'ами сделать. Тогда у тебя для каждого включения хэдэра будет по одному указателю, инициализированному адресом объекта из синглтона.
Хотя не понимаю, что мешает поместить код проверок (тот же вызов синглтона) первым оператором в main.
0
|
03.09.2011, 17:32 | |
03.09.2011, 17:32 | |
Помогаю со студенческими работами здесь
40
Препроцессор #pragma Почему не работает препроцессор? Препроцессор,исключительные ситуации Почему не рекомендуется использовать препроцессор? Препроцессор неправильно интерпретирует команды #if #else Avr c/c++ препроцессор для макроса PORT_x Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |