Someone asked about the meaning of the term "static" in C++. This particular term is perhaps the most overworked one in the language. It's both a descriptive word and a C++ keyword that is used in various ways.
"static" as a descriptive term refers to the lifetime of C++ memory or storage locations. There are several types of storage:
- static - dynamic (heap) - auto (stack)
A typical storage layout scheme will have the following arrangement, from lowest to highest virtual memory address:
text (program code) static (initialized and uninitialized data) heap (large virtual address space gap) stack
with the heap and stack growing toward each other. The C++ draft standard does not mandate this arrangement, and this example is only an illustration of one way of doing it.
Static storage thus refers to memory locations that persist for the life of the program; global variables are static. Stack storage comes and goes as functions are called ("stack frames"), and heap storage is allocated and deallocated using operators new and delete. Note that usage like:
void f() { static int x = 37; }
also refers to storage that persists throughout the program, even though x cannot be used outside of f() to refer to that storage.
So we might say that "static" as a descriptive term is used to describe the lifetime of memory locations. static can also be used to describe the visibility of objects. For example:
static int x = 37; static void f() {}
says that x and f() are not visible outside the source file where they're defined, and
void f() { static int x = 47; }
says that x is not visible outside of f(). Visibility and lifetime are not the same thing; an object can exist without being visible.
So far we've covered the uses of static that are found in C. C++ adds a couple of additional twists. It is possible to have static members of a C++ class:
class A { public: static int x; static void f(); int y; }; int A::x = 0; void A::f() {}
A static data member like A::x is shared across all object instances of A. That is, if I define two object instances:
A a1; A a2;
then they have the same x but y is different between them. A static data member is useful to share information between object instances. For example, in issue #010 we talked about using a specialized allocator on a per-class basis to allocate memory for object instances, and a static member "freelist" was used as part of the implementation of this scheme.
A static function member, such as A::f(), can be used to provide utility functions to a class. For example, with a class representing calendar dates, a function that tells whether a given year is a leap year might best be represented as a static function. The function is related to the operation of the class but doesn't operate on particular object instances (actual calendar dates) of the class. Such a function could be made global, but it's cleaner to have the function as part of the Date package:
class Date { static int is_leap(int year); // use bool if available public: // stuff };
In this example, is_leap() is private to Date and can only be used within member functions of Date, instead of by the whole program.
static meaning "local to a file" has been devalued somewhat by the introduction of C++ namespaces; the draft standard states that use of static is deprecated for objects in namespace scope. For example, saying:
static int x; static void f() {}
is equivalent to:
namespace { int x; void f() {} }
That is, an unnamed namespace is used to wrap the static declarations. All unnamed namespaces in a single source file (translation unit) are part of the same namespace and differ from similar namespaces in other translation units.
There's one additional interesting angle on the use of static. Suppose that you have:
class A { public: A(); ~A(); }; void f() { static A a; }
This object has a constructor that must be called at some point. But we can't call the constructor each time that f() is called, because the object is static, that is, exists for the life of the program, and should be constructed only once. The draft standard says that such an object should be constructed once, the first time execution passes through its declaration.
This might be implemented internally by a compiler as:
void f() { static int __first = 1; static A a; if (__first) { a.A::A(); // conceptual, not legal syntax __first = 0; } // other processing }
If f() is never called, then the object will not be constructed. If it is constructed, it must be destructed when the program terminates.
India seo freelance web designer India web development ecommerce website developer India
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100