[ fromfile: statics.xml id: statics ]
The keyword static
can be applied to local variables, class members, and global
variables/functions. In each case, static
means something different.
The keyword static
can be applied to a local variable declaration to give the
variable static storage class (Section 20.3).
A local static
variable is created only once and initialized the first time its
declaration statement is processed by the running program.
It is destroyed when the program terminates.
A nonlocal static
is created once, when the object module is loaded into memory, and
is destroyed when the program terminates.
A static
data member is a piece of data associated with the class itself rather than
one that belongs to a particular object.
It does not affect the sizeof()
an object of the class.
Each object of a class maintains its own set of non-static
data members,
but there is only one instance of any static
data member, and it is shared by all
objects of the class.
static
members are preferable to (and can generally replace the use of) global
variables because they do not add unnecessary names to the global namespace.
Global Namespace Pollution | |
---|---|
Adding names to the the global scope (e.g., by declaring global variables or global functions) is called global namespace pollution and is regarded as bad programming style. There are many good reasons to avoid declaring global variables in your programs. One is that it increases the likelihood of name collisions and confusion. Some experts use the number of global names in a program as an inverse measure of the program's quality (the lower the number, the higher the quality). |
static
class members must be declared static
in (and
only in) the class definition.
Example 2.9. src/statics/static.h
[ . . . . ] class Thing { public: Thing(int a, int b); ~Thing(); void display() const ; static void showCount(); private: int m_First, m_Second; static int s_Count; }; [ . . . . ]
Figure 2.3
shows a UML class diagram for class Thing
from Example 2.9.
Notice that the static
members are underlined in the diagram.
A class member function that does not in any way access the non-static
data members
of the class can (and should) be declared static.
In Example 2.9, the
static
data member is a private counter that keeps track of the number of Thing
objects that exist at any given moment.
The public static
member function displays the current value of the static
counter.
Each static
data member must be initialized (defined) once outside the class definition, preferably in the
corresponding class implementation file. [28]
Example 2.10 shows
how to initialize and use static
members.
Example 2.10. src/statics/static.cpp
#include "static.h" #include <iostream> int Thing::s_Count = 0; Thing::Thing(int a, int b) : m_First(a), m_Second(b) { ++s_Count; } Thing::~Thing() { --s_Count; } void Thing::display() const { using namespace std; cout << m_First << "$$" << m_Second; } void Thing::showCount() { using namespace std; cout << "Count = " << s_Count << endl; }
Note | |
---|---|
Notice that the term |
static
s defined inside a function or a block of code are initialized when they are
executed for the first time.
long nextNumber() { int localvar(24); static long statNum = 1000; cout << statNum + localvar; return ++statNum; }
The first call to nextNumber()
initializes localvar
to
24
and statNum
to 1000
,
displays 1024
on the screen, and returns 1001.
When the function returns, localvar
is destroyed but statNum
is not.
Each time that this function is called, localvar
gets created and initialized to
24
again.
The static variable statNum
persists between calls and holds onto the value that it
obtained in the last call.
So, for example,
the next time the function is called, 1025
is displayed and 1002
is returned.
static
Initialization
A static
object that is not defined in a block or function is initialized when its
corresponding object module[29] is
loaded for the first time.
Most of the time, this is at program startup, before main()
starts.
The order in which modules get loaded and variables get initialized is implementation-dependent, so you should
never make an initialization depend on the initial value of a static from a different file, even if you list that
file first when compiling.
A static
object is constructed once and persists until the program terminates.
A static
data member is a static
object that has class
scope.
In Example 2.11, we make use of an internal block so that we can introduce some local objects that will be destroyed before the program ends.
Example 2.11. src/statics/static-test.cpp
Here is the compile and run.
src/statics> g++ -Wall static.cpp static-test.cpp src/statics> ./a.out Count = 0 Count = 2 Count = 4 Count = 2 src/statics>
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |