Объявление класса в заголовочном файле и статические переменные

Нубский вопрос, но хотелось бы понять следующее:

Представьте, что у меня есть многофайловый проект. Я указываю класс в заголовочном файле, который будет использоваться всеми файлами проекта, и пишу следующее: static int test = 0;, а в следующей строке: static const int MAX = 4;

Первым будет ошибка при попытке компиляции из-за одного правила определения. Но второй скомпилируется без ошибок. Почему?

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

Любая помощь?

РЕДАКТИРОВАТЬ: проверка объявления внешней константы в заголовке: extern const int MAX = 4; для принудительной внешней связи привела к ожидаемой ошибке. Поэтому я не понимаю, почему с переменной это дает мне ошибку, а с константой - нет.


person Kurospidey    schedule 17.08.2012    source источник
comment
Вы имели в виду static const int MAX = 4;?   -  person Tom Kerr    schedule 17.08.2012
comment
@ Том Керр, ой, извини. исправлено.   -  person Kurospidey    schedule 17.08.2012
comment
@ Том, разве в C++ нет правила int по умолчанию?   -  person Qnan    schedule 17.08.2012
comment
@Qnan Я предположил, что он имел в виду int, но я не хотел редактировать и менять смысл его вопроса. Если он (или другие, читающие вопрос позже) не знал, то вопрос задает разные вещи. Однако я полагаю, что они эквивалентны.   -  person Tom Kerr    schedule 17.08.2012


Ответы (2)


Пытаться

static const int test = 0;

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

class MyClass
{
    // ...
    static const int test;
    // ...
}

и инициализируйте его в соответствующем файле .cpp

const int MyClass::test = 0;

Это должно корректно работать и с любыми другими типами, кроме int.

person πάντα ῥεῖ    schedule 17.08.2012

Целочисленные константы в C++ на самом деле не занимают места в объекте и вообще не ведут себя как переменные. Думайте о них больше как о числах, которым даются имена в данном конкретном контексте.

person Qnan    schedule 17.08.2012
comment
@Qnan Но я заявляю одно и то же во всех файлах. Это должно быть ошибкой. Константы, объявленные извне без статики, имеют внутреннюю связь, позволяющую добавлять их в файлы заголовков. Но в данном случае я использую static. - person Kurospidey; 17.08.2012
comment
@Kurospidey нет, оно помещается в особое место в памяти, и всякий раз, когда вы используете его в коде, компилятор, скорее всего, заменит имя фактическим значением. т.е. с константами нет объявления/определения, это просто дает номеру новое имя. - person Qnan; 17.08.2012
comment
@Kurospidey, static форсирует внутреннюю связь, вы все перепутали . - person Lol4t0; 17.08.2012
comment
@Qnan, так не будет ли компилятор протестовать за то, что номеру дважды присвоено новое имя? Таким образом, я могу поставить две строки одну за другой: const int MAX = 4; константный интервал МАКС = 4; - person Kurospidey; 17.08.2012
comment
@Kurospidey, это зависит от компилятора. Я ожидаю, что вы получите как минимум предупреждение и, скорее всего, ошибку, так как это не имеет смысла. Однако #include‹› не так глуп, как вам кажется :) Он не просто вставляет код в каждый исходный файл, по крайней мере, так я считаю. - person Qnan; 17.08.2012
comment
@Qnan, спасибо за помощь. я попробовал то, что сказал, и компилятор не дал мне никаких ошибок. OTOH, я протестировал объявление константы в заголовочном файле как extern const MAX = 4; чтобы переопределить внутреннюю связь по умолчанию, и компилятор выдал мне ошибку. Я не понимаю разницы между переменной и константой. Если я не могу инициализировать переменную в заголовке из-за одного правила определения, я также не смогу инициализировать константу. И если то, что вы сказали, всегда было правдой, принуждение const к внешней связи с extern не должно вызывать ошибок... - person Kurospidey; 17.08.2012