Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
 Аватар для Джон Кофи
266 / 81 / 18
Регистрация: 05.04.2018
Сообщений: 1,102
Записей в блоге: 1

Почему (для чего?) нельзя инициализировать статик переменную внутри класса?

19.03.2019, 14:58. Показов 2701. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет. Почему (для чего?) нельзя инициализировать статик переменную внутри класса? И какие есть нюансы в работе? Спасибо.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.03.2019, 14:58
Ответы с готовыми решениями:

Почему в начале класса нельзя инициализировать переменную?
public partial class Winter : Form { List<string> list = new List<string>; list = new List<string>(); Вот...

Почему нельзя присвоить переменным a, b, c, d значения тексбоксов внутри класса
Почему нельзя присвоить переменным a,b,c,d значения тексбоксов внутри класса? public class Rectangle { public...

Почему нельзя инициализировать словарь таким образом?
Dictionary<char, int> d2 = new Dictionary<char, int>() {new KeyValuePair<char, int>('a', 1), ...

27
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.03.2019, 23:33
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от zayats80888 Посмотреть сообщение
ну либо const, либо inline
Еще раз
Цитата Сообщение от http://eel.is/c++draft/class.static.data#3
If a non-volatile non-inline const static data member is of integral or enumeration type, ... shall still be defined in a namespace scope if it is odr-used in the program and the namespace scope definition shall not contain an initializer.
Здесь говорится что такой член класса, объявленный как static const, должен быть по прежнему определен в области пространства имен (а не в определении класса).
В то время как
Цитата Сообщение от http://eel.is/c++draft/class.static.data#3
An inline static data member may be defined in the class definition and may specify a brace-or-equal-initializer.
Член класса объявленный как inline static может быть определен внутри класса.
Итог
C++
1
2
3
struct X {
    static int const n = 7; // должен быть определен вне класса, но компилится без проблем
};
в то время как
C++
1
2
3
struct X {
    static inline int n = 7; // тут все ок
};
С другой стороны, так делать нельзя
C++
1
2
3
struct X {
    static int n = 10;
};
надо писать так
C++
1
2
3
4
5
6
// в хедере
struct X {
    static int n;
};
// в спп
int X::n = 0;
Но как уже сказала eva2326, между этими записями нету особого различия и как я понимаю константность это подтвреждает. Вопрос что такого делает const что разрешает инициализировать внутри класса? По идее можно разрешить инициализировать статик переменные в общем случае, со шаблонами же нету проблем? Тем более как видно из стандарта на самом деле это не должно работать (инициализация static const внутри класса) или я понял не верно?
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
20.03.2019, 11:44
UPD.
Вобщем, дам ответы на свои же вопросы вдруг кому будет интересно
Цитата Сообщение от Azazel-San Посмотреть сообщение
Здесь говорится что такой член класса, объявленный как static const, должен быть по прежнему определен в области пространства имен (а не в определении класса).
Цитата Сообщение от Azazel-San Посмотреть сообщение
C++
1
2
3
struct X {
    static int const n = 7; // должен быть определен вне класса, но компилится без проблем
};
Все верно, не inline const static члены класса не определяются объявлением в определении класса. Это значит что они должны быть определены вне класса (за исключением inline с С++17), если они odr-used.
Цитата Сообщение от Azazel-San Посмотреть сообщение
Вопрос что такого делает const что разрешает инициализировать внутри класса?
Статические объекты не нужно определять, если они не odr-used. Неспособность определить объект, который odr-used, не гарантируется что будет продиагностирован компилятором. Эта оптимизация может удалить odr-used объект, чтобы он не проявился как ошибка.
Цитата Сообщение от http://eel.is/c++draft/basic.def.odr#4
A variable x whose name appears as a potentially-evaluated expression e is odr-used by e unless
  1. x is a reference that is usable in constant expressions, or
  2. x is a variable of non-reference type that is usable in constant expressions and has no mutable subobjects, and e is an element of the set of potential results of an expression of non-volatile-qualified non-class type to which the lvalue-to-rvalue conversion is applied, or
  3. x is a variable of non-reference type, and e is an element of the set of potential results of a discarded-value expression to which the lvalue-to-rvalue conversion is not applied.
Цитата Сообщение от Azazel-San Посмотреть сообщение
Значит Cтрауструп нас обманывает?
Нет, в плане "complicated linker rules" - все правда.
Но и слова сказанные о шаблонах имееют смысл. Эти сложные правила компоновщика были необходимы, чтобы сделать возможным использование шаблонных статических переменных. И способность определять даже не шаблонные статические переменные имеет свои преимущества. Это, вероятно, причины, по которым комитет решил разрешить определение статических членов в определении класса в C++17.
1
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
20.03.2019, 12:53
Цитата Сообщение от Azazel-San Посмотреть сообщение
Нет, в плане "complicated linker rules" - все правда.
Если бы это было правдой, в шаблонах нельзя было бы определять статические данные-члены.

Но ведь инженеры как то же смогли решить проблему статиков в шаблонах?
И теперь, раз уж проблема уже решена,
почему бы не позволить инициализировать статики в хедерах и для обычных классов тоже?

Цитата Сообщение от Azazel-San Посмотреть сообщение
вероятно, причины, по которым комитет
Так долго забивал на возможность инициализировать статические члены в объявлении класса можно очень просто объяснить: комитету пофигу))

Никто ж не жалуется, что без этой фичи жить не может.
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
20.03.2019, 13:00
Цитата Сообщение от eva2326 Посмотреть сообщение
Если бы это было правдой, в шаблонах нельзя было бы определять статические данные-члены.
Но ведь в отрыве от шаблонов это таки правда.
А шаблоны требуют отдельных правил и эти правила были сделаны, для них, но совсем забыли об обычных статиках.. Эх..
Цитата Сообщение от eva2326 Посмотреть сообщение
И теперь, раз уж проблема уже решена,
почему бы не позволить инициализировать статики в хедерах и для обычных классов тоже?
Воот, это конечно главный вопрос. Теории которые описывают данную проблему, я описал, а именно то что это может быть способ для реализации оптимизировать сгенерированный код. Статические члены без const могут быть опущены, если они не используются. Если они используются, то они могут быть инициализированы только во время выполнения. Следовательно, они должны быть определены вне класса.
Цитата Сообщение от eva2326 Посмотреть сообщение
комитету пофигу))
Есть такое, смотря на градущий С++20 ни чуть в этом не сомневаюсь.
Цитата Сообщение от eva2326 Посмотреть сообщение
Никто ж не жалуется, что без этой фичи жить не может.
Если честно, то я бы начал ))
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
20.03.2019, 14:04
Цитата Сообщение от Azazel-San Посмотреть сообщение
Но ведь в отрыве от шаблонов это таки правда.
Что значит "в отрыве"?
У инженеров уже на руках есть готовая технология, как сделать приличный статик-член.
Просто её никто не внедряет дальше шаблонов.


Это как в случае с лямбдами.
Специально ради поддержки лямбд, были разработаны технологии:
C++
1
[](auto&& arg) { return check(arg); }
1. Вывод типа возвращаемого функцией.
2. Вывод типов аргументов функции.

Среди комитетчиков затесался иллюминат, который озаботился,
и в итоге первую технологию распространили на все функции.
Почему бы и нет, если для этого уже есть готовая рабочая технология?
Теперь для любой функции можно использовать автоматический вывод возвращаемого значения:
C++
1
auto foo() { return this->isReady(); }
А вот вторую технологию этот иллюминат таки не протолкнул.
В итоге, даже несмотря на наличие действующей технологии
Кликните здесь для просмотра всего текста
gcc уже сегодня поддерживает синтаксис:
C++
1
auto foo(const auto&);

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

Как и в случае со статиками: комитету пофигу.
Никто ж не жалуется на остутствие фичи.
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
20.03.2019, 14:10
Цитата Сообщение от eva2326 Посмотреть сообщение
Просто её никто не внедряет дальше шаблонов.
Причем как я понимаю это тянется еще из с++98?
Так почему никто не обращает на это внимание? А, ну да,
Цитата Сообщение от eva2326 Посмотреть сообщение
комитету пофигу))
Цитата Сообщение от eva2326 Посмотреть сообщение
gcc уже сегодня поддерживает синтаксис:
В С++20 вроде уже таки должны завести поддержку этого. Но вроде это не так критично (лично мне не оч нравится то что auto захватывает С++). Но критично что это таки можно было сделать еще в с++14 если не раньше..
Цитата Сообщение от eva2326 Посмотреть сообщение
Никто ж не жалуется на остутствие фичи.
Никто - это скорее всего никто из комитета?
Думаю есть много людей которые заметили эту несправедливость.
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
20.03.2019, 14:14
Цитата Сообщение от Azazel-San Посмотреть сообщение
Никто - это скорее всего никто из комитета?
Из массонских лож...

Цитата Сообщение от Azazel-San Посмотреть сообщение
Думаю есть много людей которые заметили эту несправедливость.
Где митинги? С плакатами и с транспорантами?
Забастовки, стачки, восстания?
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
20.03.2019, 14:22
Цитата Сообщение от eva2326 Посмотреть сообщение
Где митинги? С плакатами и с транспорантами?
Забастовки, стачки, восстания?
Жрут г****? Значит их все устраивает или устраивает отношение комитета на эту и множество других ситуаций?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.03.2019, 14:22
Помогаю со студенческими работами здесь

Конструктор класса не дает инициализировать переменную класса
Привет. Вот такой вот класс. Когда пытаюсь в конструкторе присвоить name и hobby что либо, пишет ошибку: выражение должно быть допустимым...

Как инициализировать глобальную переменную внутри блока if
есть глобальная переменная класса - hername, мне нужно ее инициализировать в этой строчке hername = object.objectForKey("name")...

Как инициализировать переменную перед использованием внутри условия?
if(m1 == 0) { z1 = 100; } else if (m1 == 1) { ...

Как инициализировать this внутри класса
Доброго времени суток. Подскажите пожалуйста, как решить данную проблему. struct Test { void F() { this = new Test; //Как...

Как инициализировать массив внутри класса?
Есть класс. Внутри обычные элементы. И нужно как то добавить туда массив. Язык С++


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

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru