For the basic informal meaning of "constant" you have #define
, const
and enum
, as already mentioned by other answers.
But at least as I'm writing this, nobody has yet discussed how to use them.
First, I'm sure you know that Macros Are Evil, so I shall not belabor the point: just say "no" to #define
(as a means of defining constants).
Second, the enum
comes in handy when you need to define a constant static
member of integral type, in code that should be portable to older compilers.
Third, for the formal meaning of "define" there is a perhaps very surprising subtlety:
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.
}
Part of the subtlety is the exchange of the visual form of pure declaration versus definition. In just about any other context it's the declaration with initialization that is also the definition. But not for this static member of integral type!
And part of the subtlety is that without the definition, somewhere, you can't formally take the address of Blah::x
; it's the definition that, formally, gives it storage.
And, part of the subtlety is that for no good reason other than historical accident, you can only do the above for integral types, not for e.g. double
, or a string, whatever.
struct Blah
{
static double const x = 3.14; // !CAN NOT DO THIS IN C++98.
};
To effectively create a member constant of, say, type double
, you can use the templated constant idiom as a workaround. Effectively doing the compiler's job, what it in principle could have rewritten the above as. It goes like this:
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.
}
For example, you might want to employ that trick for defining class Blah
completely in a header file.
It works due to special support for class templates -- because without that special rule, it would be practically impossible to define class templates with static
member constants, in header files.
Cheers & hth.,