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

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

19.03.2019, 14:58. Показов 2698. Ответов 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, 15:04
Цитата Сообщение от Джон Кофи Посмотреть сообщение
Почему (для чего?) нельзя инициализировать статик переменную внутри класса?
Что бы не нарушать ODR.
А вообще можно, начиная с С++17, можно писать так:
A static data member may be declared inline. An inline static data member can be defined in the class definition and may specify an initializer. It does not need an out-of-class definition:
C++
1
2
3
struct X {
     inline static int n = 1; 
};
1
19.03.2019, 15:06

Не по теме:

Цитата Сообщение от Azazel-San Посмотреть сообщение
посать так:
:good:

0
 Аватар для Джон Кофи
266 / 81 / 18
Регистрация: 05.04.2018
Сообщений: 1,102
Записей в блоге: 1
19.03.2019, 16:51  [ТС]
Цитата Сообщение от Azazel-San Посмотреть сообщение
C++
1
2
3
struct X {
* * *inline static int n = 1; 
};
про inline знаю, что компиляторы у нас умные и скорее всего проигнорят встраивание. Можно попросить настойчивее
C++
1
2
3
4
//ms vc
_forceinline void foo() {}
//gcc
_attribute_((always_inline))void foo() {}
но и тут гарантий нет.
а в Вашем примере inline точно не проигнорится?
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.03.2019, 16:52
Цитата Сообщение от Джон Кофи Посмотреть сообщение
а в Вашем примере inline точно не проигнорится?
Стандарт вроде как гарантирует, за древенйшие компиляторы не уверен.
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
19.03.2019, 17:22
Цитата Сообщение от Джон Кофи Посмотреть сообщение
у нас умные и скорее всего проигнорят встраивание.
Если что, то это не тот inline, который у функций.
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.03.2019, 17:28
Цитата Сообщение от Croessmah Посмотреть сообщение
Если что, то это не тот inline, который у функций.
А почему тогда сделали смягчения правила?
Если я не ошибаюсь запрет на инициализировать статик переменных внутри класса, сделали из-за возможного нарушения ODR таком случае?
Вот что говорит Страуструп, на этот счет.
A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.
Вот что говорил стандарт, в том числе и для static const
§9.4.2/4 If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a name- space scope if it is used in the program and the namespace scope definition shall not contain an initializer.
inline - для функций разрешает избежать нарушения ODR, то логика inline - для статик филдов класса не похожая?
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
19.03.2019, 18:13
Цитата Сообщение от Azazel-San Посмотреть сообщение
запрет на инициализировать статик переменных внутри класса, сделали из-за возможного нарушения ODR таком случае?
Очевидно жеж, что нет))

Как вы себе вообще представляете такую ошибку?

Цитата Сообщение от Azazel-San Посмотреть сообщение
Вот что говорит Страуструп, на этот счет.
Что говорит Страуструп насчет шаблонов?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// шаблоны целиком запихивают в хэдера
 
template<class T>
struct haha
{
    static int val;
};
 
 
// но как то же компиляторы разруливают тот факт,
// что статический член класса инициализируется в хедере
// (вне единицы трансляции)
template<class T>
int haha<T>::val = 0;
 
 
int main()
{
    haha<int> v;
}

Цитата Сообщение от Azazel-San Посмотреть сообщение
nline - для функций разрешает избежать нарушения ODR
Не путайте "ошибки ODR" с "многократно определенной функцией"


inline разрешает множественное определение одной и той же функции
(в последствии лишние копии будут выпилены линкером),
но никак не защищает от ошибок ODR
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.03.2019, 18:52
Цитата Сообщение от eva2326 Посмотреть сообщение
Очевидно жеж, что нет))
А разве static внутри класса не похож на определение переменной в неймспейсе со специпикатором extern?
Тогда у нас на всю программу должен быть один такой опредленный (defined) статик?
А класс может быть определен в каждой единице трансляции?
Цитата Сообщение от eva2326 Посмотреть сообщение
Что говорит Страуструп насчет шаблонов?
Значит Cтрауструп нас обманывает?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.03.2019, 18:56
del
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.03.2019, 19:04
Нашел такое:
Цитата Сообщение от http://eel.is/c++draft/class.static.data#2
The declaration of a non-inline static data member in its class definition is not a definition and may be of an incomplete type other than cv void. The definition for a static data member that is not defined inline in the class definition shall appear in a namespace scope enclosing the member's class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator. The initializer expression in the definition of a static data member is in the scope of its class.
[ Example:
C++
1
2
3
4
5
6
7
class process {
  static process* run_chain;
  static process* running;
};
 
process* process::running = get_main();
process* process::run_chain = running;
The static data member run_*chain of class process is defined in global scope; the notation process::run_*chain specifies that the member run_*chain is a member of class process and in the scope of class process. In the static data member definition, the initializer expression refers to the static data member running of class process. — end example ] [ Note: Once the static data member has been defined, it exists even if no objects of its class have been created. [ Example: In the example above, run_*chain and running exist even if no objects of class process are created by the program. — end example ] — end note ]
Но проясняет не многое.
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
19.03.2019, 19:05
Цитата Сообщение от Azazel-San Посмотреть сообщение
А класс может быть определен в каждой единице трансляции?
Когда десяток ваших спп прицепляют один и тот же хедер:
C++
1
#include "myclass.h>
Как думаете, что происходит?

Цитата Сообщение от Azazel-San Посмотреть сообщение
А разве static внутри класса не похож на определение переменной в неймспейсе со специпикатором extern?
Похож))

Цитата Сообщение от Azazel-San Посмотреть сообщение
Значит Cтрауструп нас обманывает?
Обманывает)
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.03.2019, 19:12
Цитата Сообщение от eva2326 Посмотреть сообщение
Как думаете, что происходит?
Цитата Сообщение от eva2326 Посмотреть сообщение
Похож))
Т.е.
C++
1
2
3
struct X {
    static int n = 0;
};
это было бы тоже что и
C++
1
extern int n = 0;
И когда мы бы инклудили наш класс он же хедер к спп, определялись бы символы типо X::n инициализированные как 0?
Линкеру бы это явно не понравилось?
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
19.03.2019, 19:28
Цитата Сообщение от Azazel-San Посмотреть сообщение
это было бы тоже что и
extern int n = 0;
Нееет.
Вот так:

C++
1
2
// header.h
extern int n;
C++
1
2
// header.cpp
int n = 0;
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.03.2019, 19:32
Цитата Сообщение от eva2326 Посмотреть сообщение
Нееет.
Вот так:
Но ведь
Цитата Сообщение от Azazel-San Посмотреть сообщение
C++
1
static int n = 0; // <-- так делать нельзя
Поэтому я написал так
Цитата Сообщение от Azazel-San Посмотреть сообщение
C++
1
extern int n = 0; // что типо тоже не верно
Цитата Сообщение от eva2326 Посмотреть сообщение
Вот так:
А в вашем случае это было бы так
C++
1
2
3
4
struct X {
    static int n;
};
int X::n = 0;
?
Или не так?
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
19.03.2019, 19:51
Цитата Сообщение от Azazel-San Посмотреть сообщение
А в вашем случае это было бы так
struct X {
* * static int n;
};
int X::n = 0;
Аха.

Технически:

C++
1
2
3
4
struct X {
    static int n;
};
int X::n = 0;
и

C++
1
2
3
struct X {
    static int n = 10;
};
Это одно и тоже.
Только выглядит по разному.
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.03.2019, 20:04
Цитата Сообщение от eva2326 Посмотреть сообщение
Только выглядит по разному.
Соглашусь, только С++ думает иначе)
Но так уже все окей
C++
1
2
3
struct X {
    static int const n = 10;
};
Что здесь квалификатор 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? Но код выше с const компилится на ура?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.03.2019, 20:11
Цитата Сообщение от Azazel-San Посмотреть сообщение
Но код выше с const компилится на ура?
да, но присвоить новое значение нельзя
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.03.2019, 20:18
zayats80888, И? К чему это сказано?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
19.03.2019, 21:07
Цитата Сообщение от Azazel-San Посмотреть сообщение
И? К чему это сказано?
Цитата Сообщение от Azazel-San Посмотреть сообщение
Что-то я не пойму, определен внутри класса может быть только inline?
ну либо const, либо inline
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.03.2019, 21:07
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 из исходников с помощью 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