Подтвердить что ты не робот

Почему переменные статические переменные должны быть инициализированы вне класса?

Я знаю, что непостоянные статические переменные необходимо инициализировать вне определения класса, но есть ли причина для этого?

class A {
    static int x = 0 // compile error;
    static int y;
};

int A::y = 0; // fine
4b9b3361

Ответ 1

По существу это потому, что x существует независимо от количества созданных экземпляров A.

Поэтому хранилище для x должно быть определено где-то - вы не можете полагаться на экземпляр A, чтобы сделать это, и что

A::x = 0;

ровно одна единица перевода, делает.

Ответ 2

Когда присутствует квалификатор const, статическая переменная может рассматриваться как константное выражение. Инициализация его в определении класса идет на этот счет. Это просто некоторая постоянная ценность, может даже не нуждаться в каком-либо хранилище.

Но в другом случае это не постоянное выражение. Это определенно нуждается в хранении. И, как указывает @Bathsheba, его нужно определить только в одной единицы перевода (pre-С++ 17). Вообще говоря, объявление, содержащее инициализатор, также является определением. Поэтому он не может быть инициализирован при объявлении.


Начиная с С++ 17, эта переменная может быть встроенной переменной. Таким образом, определение действительно может быть включено в объявление класса

class A {
  static inline int x = 0;
};

И компилятор будет сортировать все эти объявления для обозначения одного и того же хранилища.

Ответ 3

после небольшого исследования, нашел это (от bogotobogo):

мы не можем инициализировать статическую переменную-член внутри объявления класса. Это потому, что объявление - это описание того, как распределяется память, но не выделяет память. Мы выделяем и инициализируем память, создавая объект с использованием этого формата.

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

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



мой прием от этого есть.

статические члены существуют как члены класса, а не как экземпляр в каждом объекте класса.

когда вы инициализируете статическую переменную внутри объявления класса, в качестве концепции она будет повторно инициализирована (а не фактическое поведение) при каждом создании объекта/экземпляра класса, [поскольку объявление класса - это проект, для которого каждый новый объект класса является конструкцией].

но мы знаем, что это не должно быть поведение статического члена, поэтому инициализация этого элемента вне объявления класса.

Я нашел это объяснение более интуитивным, но формальное объяснение остается первым.

Ответ 4

Кроме того, что говорили другие, в классе нет места (pre С++ 11), в котором вы могли бы инициализировать статический член (поскольку члены (как статические, так и нестатические не могут быть инициализированы там, где они объявлены). нестатические члены, мы используем либо constructor, либо member initializer list для инициализации. Но это означает, что мы должны создать экземпляр класса.

Поскольку инициализация статического члена не может зависеть от создаваемого экземпляра, это делается вне класса, в котором объявлен член.