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

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

В C и С++ все статические переменные по умолчанию инициализируются ZERO.

Это не относится к элементам данных статического класса. Почему это?

#include <iostream>
using namespace std;

int var;

class MyClass
{
public:
    static int classVar;
};
int MyClass::classVar = 0;  // Why I have to init it here?

int main(void)
{
    cout << ::var << endl;          // this is initalized to ZERO by default
    static int var;
    cout << var << endl;            // and this also is initalized to Zero
    cout << MyClass::classVar << endl;

    return 0;
}
4b9b3361

Ответ 1

В области класса

int MyClass::classVar = 0;  // Why I have to init it here?

- определение и

static int classVar;

- объявление , т.е. обещание, что переменная будет определена где-то: вы должны точно определить, как только вы укажете переменные.

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

Обратите внимание, что в соответствии с правилами инициализации значения вы можете согласиться с

int MyClass::classVar;  // Zero-initialized !

как определение.

Переменные, объявленные в области пространства имен, также являются определениями (если только они не соответствуют extern):

int var;

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

[Обратите внимание, что в С++ (а не в C), если var выше const, он автоматически становится static, и нет нарушения правила One Definition, если оно будет помещено в многократно включенное заголовок. Это немного не соответствует теме, но не стесняйтесь спрашивать подробности]

Ответ 2

С++ FAQ 10.12 гласит, что:

статические члены данных должны быть явно определены точно в одном модуле компиляции.

Из С++ FAQ http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12

Отвечает ли это на ваш вопрос или вы после ссылки на сам стандарт С++?

Ответ 3

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

Типы переменных имеют логическое "нулевое значение", для int оно равно 0, для double 0,0, для string "" и т.д. Напротив, классы не обязательно имеют значение по умолчанию. Рассмотрим, например, class Rectangle. Каково его нулевое значение - прямоугольник с нулевым квадратом или прямоугольник с длиной стороны блока? Для статических переменных компилятор просит вас определить себя, какое значение должно иметь значение вашей статической переменной, поскольку не каждый тип данных может быть инициализирован значением по умолчанию.