I am trying to define a public static variable like this :
public :
static int j=0; //or any other value too
I am getting a compilation error on this very line : ISO C++ forbids in-class initialization of non-const static member `j\'.
Why is it not allowed in C++ ?
Why are const members allowed to be initialized ?
Does this mean static variables in C++ are not initialized with 0 as in C?
Thanks !
(1.) Why is it not allowed in C++ ?
From Bjarne Stroustrup\'s C++ Style and Technique FAQ: A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.
(2.) Why are const members allowed to
be initialized ?
[dirkgently said it better]
(3.) Does this mean static variables
in C++ are not initialized with 0 as
in C?
As far as I know, as long as you declare the static member var in a .cpp it will be zero-initialized if you don\'t specify otherwise:
// in some .cpp
int Test::j; // j = int();
You will have to initialize the static variable in a .cpp file and not in the class declaration.
When you declare a static variable in the class, it can used without instantiating a class.
//Header file
class Test
{
public:
static int j;
};
//In cpp file
//Initialize static variables here.
int Test::j = 0;
//Constructor
Test::Test(void)
{
//Class initialize code
}
Why is it not allowed in C++ ?
Until and unless you define it, the variable doesn\'t become a l-value.
Why are const members allowed to be initialized ?
Even in this case, a definition is required if you are going to take the address of the variable.
9.4.2 Static data members
2 The declaration of a static data
member in its class definition is not
a definition and may be of an
incomplete type other than
cv-qualified void. The definition for
a static data member shall appear in a
namespace scope enclosing the member’s
class definition. In the definition at
namespace scope, the name of the
static data member shall be qualified
by its class name using the ::
operator. The initializer expression
in the definition of a static data
member is in the scope of its class
Also, this is primarily an usage artifact so that you can write:
class S {
static const int size = 42;
float array[ size ];
};
Does this mean static variables in C++ are not initialized with 0 as
in C?
No they are:
3.6.2 Initialization of non-local variables
Variables with static storage duration
(3.7.1) or thread storage duration
(3.7.2) shall be zeroinitialized (8.5)
before any other initialization takes
place.
Though things get a bit more trickier in C++0x. All literal types can now be initialized (as opposed to only integral types in the current standard) which would mean that all scalar types (floats included) and some class types can now be initialized using an initializer in the declaration.
The short answer:
It\'s equivalent to saying extern int Test_j = 0;
.
If it did compile, what would happen? Every source file including your class\'s header file would define a symbol called Test::j initialized to 0. The linker tends not to like that.
class GetData
{
private:
static int integer; //Static variable must be defined with the extension of keyword static;
public:
static void enter(int x)
{
integer = x; //static variable passed through the static function
}
static int show() //declared and defined
{
return integer; //will return the integer\'s value
}
};
int GetData::integer = 0; //Definition of the static variable
int main()
{
GetData::enter(234); //value has been passed through the static function enter. Note that class containing static variables may not have the object in main. They can be called by scope resolution operator in main.
cout<<GetData::show();
}