Background
Static class members were introduced in C++ to allow storing a value or function common to all objects, not tied to a specific instance of the class. This is convenient for storing, for example, counters, object factories, or helper functions.
Problem
One of the challenges has always been the scope and the timing of initialization of such members, especially if there are many source files in the program. Incorrectly defining a static member leads to linker errors.
Solution
In C++, static members are declared in the class definition, but their initialization (for variables) must occur separately in a .cpp file (prior to C++17). C++17 allows initialization directly within the declaration if it is constexpr.
Example code:
class MyClass { public: static int counter; static void increment() { ++counter; } }; int MyClass::counter = 0; // initialization is MANDATORY outside the class
Key features:
this and non-static variablesWhat happens if a static member is not defined in the .cpp file?
You will get a linker error because the static variable will be declared but not defined. An exception is if static const int is initialized directly inside the class for a constexpr value.
// .h class A { public: static int x; }; // .cpp // int A::x = 0; // if commented out, there will be an error
Can you call a non-static function from a static one?
No. A static function does not have access to the this pointer and non-static members directly. Accessing requires a concrete object.
class B { int data; static void foo() { // data = 3; // error } };
Are static variables shared among all instances?
Yes, within a single executable file and process — the same value for all instances.
In the team, they forgot to define the static member in the .cpp file, and the project sometimes compiles with errors, and sometimes, when using inline initialization (not in all compilers), a "mysterious" runtime error occurs.
Pros:
Cons:
The company has a rule: static members are always defined in .cpp files for each class. For thread safety, std::mutex or atomic operations are used.
Pros:
Cons: