изменить статическую переменную-член в C++

Я пытаюсь определить класс Util со статической переменной-членом MAX_DIST в следующем смысле:

class Util{

 public:
    static double MAX_DIST;
    Util():MAX_DIST(400.0){}
};

и иметь возможность обновлять его в каком-либо другом классе, например.

Util::MAX_DIST = 387.98;

Это дает мне ошибку:

‘double Util::MAX_DIST’ is a static data member; it can only be initialized at its definition

Однако, если я инициализирую MAX_DIST в его определении, например

class Util{

 public:
    static const double MAX_DIST = 400;
    Util();
};

(Мне нужно добавить «const» в соответствии с инструкциями компилятора, иначе я получу ошибку «ISO C++ запрещает инициализацию неконстантного статического члена в классе») Теперь я не могу изменить MAX_DIST в других местах, так как теперь готовы только:

error: assignment of read-only variable ‘Util::MAX_DIST’

После безрезультатных поисков в интернете не могу найти решение этого парадокса. Кто-нибудь может мне помочь?


person yang    schedule 18.11.2012    source источник


Ответы (3)


Однако, если я инициализирую MAX_DIST в его определении

Вы путаете определение и декларацию. Вы пытаетесь инициализироваться в последнем — C++ запрещает это. Другие ответы показали вам, как выглядит определение: оно должно быть вне объявления класса и в своей собственной единице компиляции (иначе вы нарушите One Definition Правило при попытке включить заголовок в несколько исходных файлов).

Несколько слов о том, почему исходный код не работал: вы пытались поместить инициализацию в список инициализаторов конструктора. Однако этот конструктор вызывается для каждого экземпляра. Даже если этот код скомпилируется, он всегда будет сбрасывать вашу статическую переменную, а не то, что вам нужно.

person Konrad Rudolph    schedule 18.11.2012

Поместите это в свой файл Util.cpp (или любое другое имя файла):

double Util::MAX_DIST = 0;

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

Длинный ответ, цитирующий стандарт 9.4.2 $2:

Объявление статического члена данных в определении его класса не является определением и может иметь неполный тип, отличный от void с указанием cv. Определение статического члена данных должно появиться в области пространства имен, включающей определение класса члена. В определении области пространства имен имя члена статических данных должно уточняться именем его класса с использованием оператора ::. Выражение инициализатора в определении статического члена данных находится в области действия его класса (3.3.7).

person Vincenzo Pii    schedule 18.11.2012

В первом случае вы пытаетесь инициализировать статическую переменную из нестатического контекста, то есть из конструктора. Вы правы, что это неправильно.

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

double Util::MAX_DIST = 400;
person Xymostech    schedule 18.11.2012
comment
Действительно, объявление переменной вне класса решает мою проблему. Спасибо - person yang; 18.11.2012