mirror of
https://gitlab.com/fbb-git/cppannotations
synced 2024-11-16 07:48:44 +01:00
777b182edd
This allowed me to standardize the sourcetar and sf/* scripts: the base directory (containing ./git) is now empty, except for maintenance scripts, while the source files and build scripts of the annotations are stored in a subdirectory of their own.
95 lines
4.1 KiB
Text
95 lines
4.1 KiB
Text
To illustrate the use of a static data member which is a private
|
|
variable in a class, consider the following:
|
|
verb(
|
|
class Directory
|
|
{
|
|
static char s_path[];
|
|
|
|
public:
|
|
// constructors, destructors, etc.
|
|
};
|
|
)
|
|
The data member tt(s_path[]) is a private static data member. During
|
|
the program's execution only em(one) tt(Directory::s_path[]) exists,
|
|
even though multiple objects of the class tt(Directory) may exist. This
|
|
data member could be inspected or altered by the constructor, destructor or by
|
|
any other member function of the class tt(Directory).
|
|
|
|
Since constructors are called for each new object of a class, static
|
|
data members hi(initialization: static data member)
|
|
hi(static data members: initialization) are not em(initialized) by
|
|
constructors. At most they are em(modified). The reason for this is that
|
|
static data members exist em(before) any constructor of the class has been
|
|
called. Static data members are initialized when they are defined, outside of
|
|
any member function, exactly like the initialization of ordinary (non-class)
|
|
global variables.
|
|
|
|
The definition and initialization of a static data member usually occurs
|
|
in one of the source files of the class functions, preferably in a source file
|
|
dedicated to the definition of static data members, called ti(data.cc).
|
|
|
|
The data member tt(s_path[]), used above, could thus be
|
|
defined and initialized as follows in a file tt(data.cc):
|
|
verb(
|
|
include "directory.ih"
|
|
|
|
char Directory::s_path[200] = "/usr/local";
|
|
)
|
|
In the class interface the static member is actually only em(declared). In
|
|
its implementation (definition) its type and class name are explicitly
|
|
mentioned. Note also that the i(size specification) can be left out of the
|
|
interface, as shown above. However, its size em(is) (either explicitly or
|
|
implicitly) required when it is defined.
|
|
|
|
Note that em(any) source file could contain the definition of the static
|
|
data members of a class. A separate tt(data.cc) source file is advised, but
|
|
the source file containing, e.g., tt(main()) could be used as well. Of course,
|
|
any source file defining static data of a class must also include the header
|
|
file of that class, in order for the static data member to be known to the
|
|
compiler.
|
|
|
|
A second example of a useful private static data member is given below. Assume
|
|
that a class tt(Graphics) defines the communication of a program with a
|
|
graphics-capable device (e.g., a VGA screen). The initialization of the
|
|
device, which in this case would be to switch from text mode to graphics mode,
|
|
is an action of the constructor and depends on a tt(static) flag variable
|
|
tt(s_nobjects). The variable tt(s_nobjects) simply counts the number of
|
|
tt(Graphics) objects which are present at one time. Similarly, the destructor
|
|
of the class may switch back from graphics mode to text mode when the last
|
|
tt(Graphics) object ceases to exist. The class interface for this
|
|
tt(Graphics) class might be:
|
|
verb(
|
|
class Graphics
|
|
{
|
|
static int s_nobjects; // counts # of objects
|
|
|
|
public:
|
|
Graphics();
|
|
~Graphics(); // other members not shown.
|
|
private:
|
|
void setgraphicsmode(); // switch to graphics mode
|
|
void settextmode(); // switch to text-mode
|
|
}
|
|
)
|
|
The purpose of the variable tt(s_nobjects) is to count the number of
|
|
objects existing at a particular moment in time. When the first object is
|
|
created, the graphics device is initialized. At the destruction of the last
|
|
tt(Graphics) object, the switch from graphics mode to text mode is made:
|
|
verb(
|
|
int Graphics::s_nobjects = 0; // the static data member
|
|
|
|
Graphics::Graphics()
|
|
{
|
|
if (!s_nobjects++)
|
|
setgraphicsmode();
|
|
}
|
|
|
|
Graphics::~Graphics()
|
|
{
|
|
if (!--s_nobjects)
|
|
settextmode();
|
|
}
|
|
)
|
|
Obviously, when the class tt(Graphics) would define more than one
|
|
constructor, each constructor would need to increase the variable
|
|
tt(s_nobjects) and would possibly have to initialize the graphics mode.
|