Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.70
Fasterbru
5 / 5 / 2
Регистрация: 18.11.2014
Сообщений: 81
#1

Как создать глобальную константу для всего проекта? - C++

20.11.2014, 22:43. Просмотров 1719. Ответов 24
Метки нет (Все метки)

как создать?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.11.2014, 22:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как создать глобальную константу для всего проекта? (C++):

Как правильно объявить константы для всего проекта, который состоит из нескольких файлов - C++
какой-нибудь Variables.h в котором будет что-то типа: #define A 50 #define B 40 или const int A 50

Как создать глобальную переменную? - C++
Создаю небольшой проект. Несколько функций и собственно тело программы. В теле объявил переменную int rep. Далее мне надо обратиться к ней...

Как правильно создать глобальную переменную? - C++
Как правильно создать глобальную переменную? Если она будет в заголовочном файле, то при подключении этого файла к другим cpp, эта...

Как лучше всего создать форму в С++ - C++
Хочу попробовать создать не консольную программу, а графическую. Как лучше всего создавать формы?

Как проще всего создать множество? - C++
Можно ли задать это множество как-то попроще? set<char> numbers; numbers.insert('0'); numbers.insert('1'); ...

Как создать release проекта в MS Visual Studio? - C++
Здравствуе. У меня Visual 2013 Компилирую простую программку, ставлю release #include "stdafx.h" #include <iostream> ...

24
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
20.11.2014, 23:38 #2
globalconst.hpp:
C++
1
extern const int globalconst;
globalconst.cpp:
C++
1
const int globalconst = 777;
Потом инклудить globalconst.hpp где нужно. При желании можно поместить её в namespace или в статический класс.
2
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3945 / 2169 / 553
Регистрация: 18.10.2014
Сообщений: 3,783
20.11.2014, 23:45 #3
Цитата Сообщение от Fasterbru Посмотреть сообщение
как создать?
Это зависит от того, что имеется в виду под "глобальностью" и "константностью". Какого типа константа? Насколько "тяжел" этот тип?

Для скалярных типов в С++ в заголовочном файле просто пишется

C++
1
2
const int MY_GLOBAL_CONSTANT = 42;
const char *const MY_GLOBAL_STRING = "Hello";
и все. Вопрос закрыт.

Но если вы где-то в программе будете брать адрес этой константы '&MY_GLOBAL_CONSTANT', то в разных модулях этот адрес будет разным. Это вас волнует? Если волнует, то делать следует так показал true_bugmaker. Но в этом случае константа не будет константой времени компиляции в тех модулях, в которых видно только ее объявление.

Если тип вашей константы не скалярен ("тяжелый тип"), то опять же лучше поступить как показал true_bugmaker.
1
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 00:17 #4
Но если вы где-то в программе будете брать адрес этой константы '&MY_GLOBAL_CONSTANT', то в разных модулях этот адрес будет разным.
Если объявлять эту константу каждую в своём модуле, и вдруг придётся её менять, будет худо. Если константу объявить в общем заголовочном файле, линковщик грязно выругается на обилие одинаковых глобальных имён.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3945 / 2169 / 553
Регистрация: 18.10.2014
Сообщений: 3,783
21.11.2014, 00:29 #5
Цитата Сообщение от true_bugmaker Посмотреть сообщение
Если объявлять эту константу каждую в своём модуле, и вдруг придётся её менять, будет худо.
В языке C++ (в отличие от С) явно инициализированные 'const' объекты целочисленных типов образуют Integral Constant Expressions. Это настолько ценное свойство целочисленных 'const' объектов, что пожертвовать им мы не можем и ради него будем объявлять такие константы именно так, как я показал.

Разумеется, надо следить за глобальностью констант и ограничивать ее до минимальной необходимости. Т.е. не совать в действительно глобальные заголовки то, что там не нужно.

Цитата Сообщение от true_bugmaker Посмотреть сообщение
Если константу объявить в общем заголовочном файле, линковщик грязно выругается на обилие одинаковых глобальных имён.
Неправда. В языке С++ (в отличие от С) 'const' объекты имеют внутреннее связывание по умолчанию. Никакой ругани от линковщика не будет. Более того, современный компилятор вообще не создаст такого объекта в памяти, если константа нигде не используется как lvalue.
0
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 00:48 #6
http://en.wikipedia.org/wiki/One_Definition_Rule
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3945 / 2169 / 553
Регистрация: 18.10.2014
Сообщений: 3,783
21.11.2014, 01:02 #7
Цитата Сообщение от true_bugmaker Посмотреть сообщение
http://en.wikipedia.org/wiki/One_Definition_Rule
Учитесь понимать терминологию. ODR по ссылке относится только к сущностям с external linkage. Объекты, объявленные с internal linkage, образуют разные, независимые объекты в разных единицах трансляции. Поэтому множественное определение 'const' объекта в С++ в разных единицах трансляции не является нарушением ODR. Это просто определения разных, независимых объектов, а не множественное определение одного и тот же объекта.

Точно так же как определение 'static int i = 5;' в разных единицах трансляции не является нарушением ODR, определение 'const int j = 42;' в разных единицах трансляции не является нарушением ODR. В языке С++ для переменной в namespace scope 'const' эквивалентно 'static const'.

7.1.1 Storage class specifiers

6 A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration and provided it is not declared const. Objects declared const and not explicitly declared extern have internal linkage.
0
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 01:15 #8
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
ODR по ссылке относится только к сущностям с external linkage. Объекты, объявленные с internal linkage, образуют разные, независимые объекты в разных единицах трансляции. Поэтому множественное определение 'const' объекта в С++ в разных единицах трансляции не является нарушением ODR.
ТС нигде не указывал таких тонкостей своего проекта.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3945 / 2169 / 553
Регистрация: 18.10.2014
Сообщений: 3,783
21.11.2014, 01:58 #9
Цитата Сообщение от true_bugmaker Посмотреть сообщение
ТС нигде не указывал таких тонкостей своего проекта.
Я не вижу, какое отношение это может иметь к каким-то "тонкостям проекта". Это фундамент языков С и С++, который всегда присутствует во всех "проектах" без исключения.

Спецификация 'const' объектов целочисленных типов языка С++ специально разработана так, чтобы 'const int N = 42;' при правильном использовании мог выступать в качестве константы времени компиляции, т.е. в качестве замены для '#define N 42' из языка С. '#define' считается слишком грубым инструментом, так как не поддерживает типизации и не подчиняется областям видимости.

В языке С++ (в отличии от С) разрешается использовать 'const' объекты целочисленных типов, например, для задания меток case, ширин битовых полей, размеров любых массивов, инициализаторов enum констант и т.п. Но чтобы 'const' объекты можно было использовать в такой роли глобально в проекте, их инициализаторы должны быть видны во всем проекте. Т.е. поступать придется именно так, как показано в моем примере и платить за это перекомпиляцией всего проекта при изменении значения константы.

А если вам не нужно, чтобы ваша глобальная константа была константой времени компиляции, а была просто "неизменяемой переменной" (как это было в С), то можно пойти по вашему пути через 'extern const' в заголовочном файле.
0
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 02:14 #10
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Я не вижу, какое отношение это может иметь к каким-то "тонкостям проекта". Это фундамент языков С и С++, который всегда присутствует во всех "проектах" без исключения.
То есть ТС не гарантированно не огребёт проблем нарушая ODR направо и налево?
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3945 / 2169 / 553
Регистрация: 18.10.2014
Сообщений: 3,783
21.11.2014, 03:23 #11
Цитата Сообщение от true_bugmaker Посмотреть сообщение
проблем нарушая ODR направо и налево
Я не имею прямого доступа к проекту ТС и поэтому не знаю, что он там нарушает или не нарушает.

Вы, видимо, чего то не поняли. Мое объяснение выше не является каким-то трюком уровня специфического линкера. Концепции linkage (external linkage и internal linkage) - это языковые концепции, взятые непосредственно из спецификации языка. В спецификации языка нигде не сказано, что определение констант c internal linkage в заголовочном файле в С++ является нарушением ODR. Нет, не является и никогда не являлось.

Ни в языке С, ни в языке С++ невозможно нарушить ODR путем определения объектов c internal linkage в разных единицах трансляции. Это, вообще то, азы объектной модели С и С++. Меня удивляет, что приходится тратить столько времени на объяснение такой элементарщины человеку, который в состоянии найти статью про ODR в Википедии.

Зрителям: как думаете - тролль?
0
Croessmah
Ушел
Эксперт CЭксперт С++
13553 / 7704 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 1
21.11.2014, 04:22 #12
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Зрителям: как думаете - тролль?
врядли. Многие с удивлением узнают о раздельной компиляции, а тут про линковку...
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3945 / 2169 / 553
Регистрация: 18.10.2014
Сообщений: 3,783
21.11.2014, 04:45 #13
Цитата Сообщение от Croessmah Посмотреть сообщение
Многие с удивлением узнают о раздельной компиляции, а тут про линковку...
Да, но человек знает аббревиатуру ODR и приводит цитаты из стандарта (в другом треде, пусть и не до конца их понимая). В такой ситуации странно видеть, что человек не знает того элементарного факта, что, например, объявление 'static int i = 5;' или 'const int j = 10;' в заголовочном файле не приводит к нарушению ODR и никогда нарушением ODR не являлось.
0
Croessmah
Ушел
Эксперт CЭксперт С++
13553 / 7704 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 1
21.11.2014, 04:56 #14
TheCalligrapher, всё-таки я считаю, что знать и понимать это разные понятия.
0
gromo
371 / 270 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
21.11.2014, 06:10 #15
TheCalligrapher, вообще подход true_bugmaker более предпочтителен, так как константы обычно заводят для того, чтобы можно было быстренько поменять их значение и проверить работу программы. И если константа будет определена в заголовочном файле, то придется перекомпилировать все модули, куда включается этот заголовочный файл. А если завести себе отдельный файл config.cpp с константами, то перекомпилять надо будет только его ну и заново слинковать естественно.
0
21.11.2014, 06:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.11.2014, 06:10
Привет! Вот еще темы с ответами:

Как создать 2 проекта в одном solution в Visual Studio? - C++
В задании указано, что в solution должно быть 2 проекта, один чтобы читать данные, введенные с клавиатуры и записывать в бинарынй файл, а...

Где хранить глобальную переменную для всех представлений? - C++
я делаю MDI приложение с использованием БД мне нужно чтобы при запуске открывалась БД (CDatabase) а потом все формы использовали бы...

Как обьявить глобальную переменную - C++
Как объявить глобальную переменную Есть несколько *CPP* и *.h* файлы. Надо объявить переменную HWND hwnd чтобы она была доступна в...

Как обьявить глобальную переменную в функции? - C++
Вопрос как объявить переменную в функции чтобы ей можно было пользоваться везде?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru