According to the OP's Code:
#includes...
static const int GLOBAL_CONST1 = 100;
static const double GLOBAL_CONST2 = 1.0;
SomeClass::SomeClass()
:
theDataMember1 (),
theDataMember2 (),
...
{
static const double SOME_VAR = 0.01; // Why not declare this globally?
theDataMember1 = SomeIncludedClass(SOME_VAR);
}
One has to take into consideration a few things:
- Data Storage Unit - Storage Class Specifier
- Data Storage Duration - Minimum Life Of Data
- Scope Visibility - Where The Data Unit Is Visible.
Here is an excerpt:
Global objects and objects in a namespace scope, static data members of a class, and local static objects in functions reside static storage duration. An object with static storage duration resides in the same memory address throughout the program's execution. Every such object is constructed only once during the lifetime of the program. By default, static data is initialized to binary zeros. Static objects with a nontrivial constructor or an explicit dynamic initializer undergo a second initialization phase called dynamic initialization.
The scope of an object declared static in a function is restricted to that function. Objects with static storage duration appear in the following examples:
int num=0; //global variables have static storage
extern int x; //also global, defined in a separate translation unit
int func()
{
static int calls; //local static. initialized to 0 by default
x=calls;
return ++calls;
}
class C
{
private:
static bool b;
};
namespace NS
{
std::string str; //str has static storage
}
The extern Storage Class Specifier
The extern specifier can be applied only to the names of objects and to functions. The extern specifier cannot be used in the declaration of class members or function parameters. Identifiers declared extern have external linkage, meaning they are visible from all translation units of the same program.
A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration and provided it is not declared const. Objects declared const and not explicitly declared extern have internal linkage, meaning they are visible only from the translation unit in which they are declared.
Notice that the extern keyword is overloaded. It can also be used in explicit-instantiations of templates and in and linkage-specifications, but it is not a storage-class-specifier in such contexts.
The thread_local Storage Duration
The thread_local specifier indicates that the named object or reference has thread storage duration. thread_local shall be applied only to the names of objects or references of namespace scope and to the names of objects or references of block scope that also specify static as their storage class. The thread_local storage class is a new C++09 feature. It's discussed in detail here.
that can be found at this site: C++ Reference Guide | Static Storage Duration
The OP had stated and asked this:
I am working with a class whose constructor declares and initializes a static const variable in the implementation. This is not a data member of the class. I understand the use of const in this context, but what is gained by using static?
I understand that the static const global constants are shared by all instances of the class. Does that also happen with the variable inside the constructor?
Also, why would this not be defined at the Global scope, like the other two? That's where I would normally define my constants.
To answer his/her questions based on the excerpt above and from my own intuition:
- their first question:
"What is gained by using static?" static data storage units have automatic initialization. They are created only once and reside in that same memory address or allocation unit.
- their second question:
"Does that also happen with the variable inside the constructor?" Yes & No - Yes there is a single instance of this variable upon construction and initialization in the static storage memory unit, but no this is not visible to every instance of the class; it is only local to the Constructor of this class because of scope visibility.
- their final question:
"Also, why would this not be defined at the Global scope, like the other two?" This particular variable depending on intention of use might only be used in the initialization of another object. One of the benefits of this maybe to not having to use a stack variable, and is only visible to this class' constructor. So when this constructor is called
ctor
this static const variable
is created and initialize only once per construction and once this class object's constructor goes out of scope this static const variable
is no longer visible by any other function or member of this class, or any other translation unit that is outside the visibility of this scope.
There is no definitive answer, however I tried to provide as much insight as I can in regards to the OPs questions, and tried to answer them to the best of my abilities. Some of the things that can vary are the intentions of the programmer and the context in which these memory allocations units are, declared, defined, initialized and then used.