статическая переменная в классе

243
23 января 2018, 12:20

Для чего нам нужно еще раз объявлять статическую переменную вне класса, указывать область видимости, если я уже в классе определил ее как статическую(static int a):

int shared::a

?

Класс:

class shared
{
    static int a;
};
Answer 1

В классе у вас располагается объявление статического члена класса, а не определение. Определение такой переменной вы делаете именно за пределами класса как int shared::a;.

"Для чего" это делается... Это делается, в частности, для того, чтобы вы могли указать реализации:

  1. В каком порядке вы хотите инициализировать этот статический член класса, если ему нужна динамическая инициализация. Динамическая инициализация в каждой единице трансляции делается в порядке следования определений объектов, сверху-вниз. То есть то, в каком конкретном месте вы поместите определение статического члена класса, может влиять на его инициализацию.

    (В вашем случае - просто int - динамической инициализации нет, поэтому к вашему конкретному примеру это соображение не применимо.)

  2. В какой единице трансляции (в каком объектном файле) вы хотите разместить определение этого статического члена класса, т.е. из какого объектного файла оно будет экспортироваться в качестве внешнего символа.

Если для вас в вашем конкретном случае эти вопросы не имеют никакого значения, то, начиная с С++17, вы можете объявить ваш член класса как inline

class shared
{
    static inline int a;
};

и никакого дополнительного определения не понадобится. Реализация в такой ситуации сама по своему усмотрению куда-то "пристроит" определение вашей переменной.

Answer 2

А давайте представим, что это и есть - как вы хотите - определение переменной. Т.е. при таком тексте создается одна переменная класса. Не привязанная к объекту.

А теперь это объявление класса включено в N... нет, это мало... в M :) разных .cpp-файлов. И в каждом файле, получается, создается одна и та же переменная, с глобальной областью видимости.

Что делать линковщику? Если у него куча одноименных объектов?
Выбрать один? Какой именно?
Оставить все? И что тогда? В одном файле присваиваем 5, в другом - 10, в третьем читаем... что именно читаем?

Это так, краткое обоснование...

READ ALSO
Как правильно записать в std::unordered_map?

Как правильно записать в std::unordered_map?

Мне нужно в мапу histogram записать значенияЯ записываю, но выдает ошибки

277
Ожидание потока и присоединение потока <thread>. Где параллелизм?

Ожидание потока и присоединение потока <thread>. Где параллелизм?

Добрый день! Пытаюсь вникнуть в потоки и не могу понять несколько вещей:

212
реализация стека через указатели

реализация стека через указатели

При вводе 0 выводится не число на вершине стека, а какой-то мусорВ чём проблема?

289
Работа с нативным кодом из .Net Core

Работа с нативным кодом из .Net Core

У Microsoft есть статья, посвященная работе с нативным кодов вNet Core на различных платформах

254