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

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

19.03.2019, 14:58. Показов 3009. Ответов 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
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
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
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
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
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
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
Ответ Создать тему
Новые блоги и статьи
Транслитерация текста с кириллицы на латиницу (вариант №3)
Maks 15.11.2026
Обновленная версия предыдущей обработки. Изменения коснулись букв: Ъ, Ы, Ь, Э, отображения которых зависят от положения реквизита "Транслитерация имён". Изменено отображение буквы Й. Добавлена. . .
Транслитерация текста с кириллицы на латиницу (вариант №2)
Maks 13.11.2026
Обновленная версия ранее созданной обработки. Добавлено: - Проверка исходного текста на кириллицу, через обращение к стандартной функции "ТолькоКириллицаВСтроке" из общего модуля. . .
Часы с термометром и праздничным календарем
yariko 12.11.2026
Сегодня мы рассмотрим как можно сделать отличные многофункциональные часы. Итак, поставим конкретную задачу: разработать часы с календарем, двумя термодатчиками, выводом поздравительных сообщений. . .
Транслитерация текста с кириллицы на латиницу (вариант №1)
Maks 11.11.2026
Решил облегчить жизнь себе и коллегам админам при создании электронных почтовых ящиков для пользователей, в результате написал обработку "Транслитерация текста" с кириллицы на латиницу, а в ней. . .
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru