The term "static" has several meanings in C++. This can be a cause of confusion.
static local variable
Normally a local variable is allocated when a function is called and is deallocated when the function concludes:
For example:
int F(int M) { int X = 0; ... if (M == 0) return X; else { X++; return 0; } }
Here X exists only during the execution of the function F. Although we assign X a new value, that value will not remain in X when we next call F. This function will always return the value 0 when M is 0.
If we declare X as a static local variable instead, X is allocated once, the first time we call the function. It is not deallocated until the overall execution ends, and it retains its meaning and its value from one call to the function to the next. This is called static extent.
Another example:
int F(int M) { static int X = 0; ... if (M == 0) return X; else { X++; return 0; } }
Here X will be essentially a counter of the number of time the function has been called. If we call the function repeatedly with M = 0, we will have a variety of values returned.
static global variable
Global variables are declared in a source code file outside of any function, which gives them "file scope": they can be used by name by any code in that file. (In order to use a global variable in code that is in some other file, we use the term "extern". See the note on "extern".)
If a global variable is declared as static, it may not be used outside its own source code file even by using "extern". (Normally, if we do not use "static", all global variables would be visible at the linking stage.)
Why use this? Sometimes we may have several source code files, each containing some global variables, and we may have duplicate names. Using "static" provides insurance against using the wrong variable by mistake.
This use of "static" is deprecated.
static data member of a class
Normally, each instance of a class has its own data. When the instance is created, storage space is set aside for the various data members.
For example
class Widget { private: int A; public: ... }; Widget P, Q;
Here we can refer to P.A and Q.A, and these have different addresses and may have different values. We can refer to A only with reference to a paricular instance of the class. A is sometimes called an instance variable.
If we declare a data member as "static", the effect is that the data member is global to the class. There is just one, not affiliated with any particular instance.
Another example:
class Widget { private: int A; static int B; public: ... }; Widget P;
Here B belongs to the Widget class as a whole, and we refer to it as Widget::B. (We have to specify the class, as some other class might also have a static member called B.) If X is a Widget, we could refer to X.B, or if Y is a pointer to a Widget, we could refer to Y->B, but these might be considered confusing by some.
A static data member should be initialized, once, outside the class definition, in a source code file. This can be a stand-alone line of code:
Widget::B = 42;
Why use a static data member? Perhaps we want to keep a counter of the number of instances created. The constructor can increment the counter.
Sometime we may want a constant static data member. This is an exception: a constant must be initialized immediately, so we are allowed and required to initialize it in the class definition itself (which would not otherwise be permitted).
For example:
class Widget { private: const static int SIZE = 250; ... public: ... };
Sometimes a static data member is called a class variable.
static method of a class
Just as a data member can be static, we can also have static methods. A static method is again not affiliated with a specific instance of the class and does not have access to the "this" pointer or to the instance variables, as we don't have a current instance.
For example:
class Widget { private: static int Counter; int A; ... public: static int GetCounter() const; ... };
Here Counter is used to count instances of Widget. It needs to be initialized somewhere in the source code file (before we create any instances of Widget):
Widget::Counter = 0;
and the constructor for Widget presumably increments Counter:
Widget::Counter++;
The method PrintCounter simply returns the value of Counter. To print it, we need:
cout << Widget::PrintCounter();
If PrintCounter was doing something fancier, it would not have access to the instance variable A, as there is no specific instance involved.
A static method can only use other static methods and static data members (unless we pass an instance to it as an argument or create an instance as a local variable).