Для базового неформального значения "константа" у вас есть #define
, const
и enum
, как уже упоминалось в других ответах.
Но, по крайней мере, когда я пишу это, никто еще не обсуждал, как их использовать.
Во-первых, я уверен, что вы знаете, что макросы - это зло, поэтому я не буду вдаваться в подробности: просто скажите «нет» #define
(как средство определения констант).
Во-вторых, enum
пригодится, когда вам нужно определить постоянный static
член целочисленного типа в коде, который должен быть переносим на старые компиляторы.
В-третьих, для формального значения "определить" есть, возможно, очень удивительная тонкость:
struct Blah
{
static int const x = 42; // This is just a declaration, not a definition.
};
int const Blah::x; // This is a definition (yes!).
int main()
{
// Use Blah::x here.
}
Часть тонкости - это обмен визуальной формой чистого объявления с определением. Практически в любом другом контексте это объявление с инициализацией, которое также является определением. Но не для этого статического члена целочисленного типа!
И часть тонкости заключается в том, что без определения где-то вы не можете формально взять адрес Blah::x
; это определение, которое формально дает ему хранение.
И, часть тонкости заключается в том, что ни по какой веской причине, кроме исторической случайности, вы можете сделать выше только для целочисленных типов, а не, например, для double
или строка, что угодно.
struct Blah
{
static double const x = 3.14; // !CAN NOT DO THIS IN C++98.
};
Чтобы эффективно создать постоянную члена, скажем, типа double
, вы можете использовать шаблонную постоянную идиома в качестве обходного пути. Эффективно выполняя работу компилятора, то, что он в принципе мог бы переписать выше как. Это выглядит так:
template< class Dummy >
struct BlahConstants
{
static double const x;
};
template< class Dummy >
double const BlahConstants< Dummy >::x = 3.14;
struct Blah
: BlahConstants< void >
{
// Whatever.
};
int main()
{
// Use Blah::x here.
}
Например, вы можете использовать этот трюк для полного определения класса Blah
в заголовочном файле.
Это работает благодаря специальной поддержке шаблонов классов - потому что без этого специального правила было бы практически невозможно определить шаблоны классов с static
константами-членами в заголовочных файлах.
Приветствия & hth.,