The member variables of every instance of a class are different—changing one will not affect the others. There are some circumstances, however, where it would be useful to share a variable between all instances of a class. This is done by declaring the variable to be static:
A member variable that is declared static is shared by all instances of the class. Such a variable is often called a class variable.
One of the most common uses of a static member variable of a class is to store how many instances of the class are currently in existence. For example, the following class
The following class gives each new instance a unique identifying number. It does so by having a static member variable (or class variable) next_unique_id, which is initially set to 0. When the constructor is called, the current value becomes the unique identifier for that instance, and the variable is then incremented. Suppose we determined that there will never, under any circumstances, be a requirement for more than $2^16$ instances of this class, so we will restrict our unique ID to an unsigned short:
// Class_unique.h #include <cstdlib> #pragma once // Class declaration class Class_unique; // Class definition class Class_unique { public: Class_unique(); // Other public member functions unsigned short get_id(); private: unsigned short unique_id; static unsigned short next_unique_id; // Other private member functions and member variables };
// Class_unique.cpp #include "Class_unique.h" // Initialize the static member variable 'next_unique_id' to zero unsigned short Class_unique::next_unique_id = 0; Class_unique::Class_unique() { // Do other constructor things... unique_id = Class_unique::next_unique_id; ++Class_unique::next_unique_id; } unsigned short Class_unique::get_id() { return unique_id; }
If we execute the following program that uses this class, as expected, the instances a, b, c and d have unique identifiers equal to $0$, $1$, $2$ and $3$, respectively:
#include <iostream> #include "Class_unique.h" int main() { Class_unique a{}; Class_unique b{}; Class_unique c{}; std::cout << "The unique id of 'a' is " << a.get_id() << std::endl; std::cout << "The unique id of 'b' is " << b.get_id() << std::endl; std::cout << "The unique id of 'c' is " << c.get_id() << std::endl; Class_unique d{}; std::cout << "The unique id of 'd' is " << d.get_id() << std::endl; return 0; }
The following class stores the number of instances in a static member variable (or class variable) instance_count, initially set to 0. Each time the constructor is called, this variable is incremented, and each time the destructor is called, the variable is decremented.
// Class_instances.h #include <cstdlib> #pragma once // Class declaration class Class_instances; // Class definition class Class_instances { public: Class_instances(); ~Class_instances(); // Other public member functions private: static size_t instance_count; // Other private member functions and member variables };
// Class_instances.cpp #include "Class_instances.h" // Initialize the static member variable 'instance_count' to zero size_t Class_instances::instance_count = 0; Class_instances::Class_instances() { // Do other constructor things... ++instance_count; std::cout << "There are " << instance_count << " instances" << std::endl; } Class_instances::~Class_instances() { // Do other destructor things... --instance_count; std::cout << "There are now only " << instance_count << " instances" << std::endl; }
If you were to run this code on the example
#include <iostream> #include "Class_instances.h" int main() { Class_instances a{}; { Class_instances b{}; { Class_instances c{}; } // c goes out of scope; the destructor is called on it Class_instances d{}; } // b and d go out of scope; the destructor is called on each std::cout << "end of the block" << std::endl; // b goes out of scope; the destructor is called on it return 0; }
Constants that are related to a class are often public static constants:
// Class_phycis.h #pragma once // Class declaration class Class_physics; // Class definition class Class_physics { public: static double const ATOMIC_MASS_CONSTANT; // kg static double const ATOMIC_MASS_CONSTANT_ERROR; // kg static double const AVOGADRO_CONSTANT; // 1/mol static double const AVOGADRO_CONSTANT_ERROR; // 1/mol static double const BOLTZMANN_CONSTANT; // J/K static double const BOLTZMANN_CONSTANT_ERROR; // J/K static double const ELECTRON_MASS; // kg static double const ELECTRON_MASS_ERROR; // kg static double const ELEMENTARY_CHARGE; // C static double const ELEMENTARY_CHARGE_ERROR; // C static double const GAS_CONSTANT; // J/mol K static double const GAS_CONSTANT_ERROR; // J/mol K static double const GRAVITATIONAL_CONSTANT; // Nm^2/kg^2 static double const GRAVITATIONAL_CONSTANT_ERROR; // Nm^2/kg^2 static double const NEUTRON_MASS; // kg static double const NEUTRON_MASS_ERROR; // kg // And many others... // Other public declarations private: // Private member functions and member variables };
The constants are defined in the corresponding source file:
// Class_phycis.cpp #include "Class_physics.h" double const Class_physics::ATOMIC_MASS_CONSTANT = 1.660539040e-27; double const Class_physics::ATOMIC_MASS_CONSTANT_ERROR = 0.000000020e-27; double const Class_physics::AVOGADRO_CONSTANT = 6.022140857e23; double const Class_physics::AVOGADRO_CONSTANT_ERROR = 0.000000074e23; double const Class_physics::BOLTZMANN_CONSTANT = 1.38064852e-23; double const Class_physics::BOLTZMANN_CONSTANT_ERROR = 0.00000079e-23; double const Class_physics::ELECTRON_MASS = 9.10938356e-31; double const Class_physics::ELECTRON_MASS_ERROR = 0.00000011e-31; double const Class_physics::ELEMENTARY_CHARGE = 1.6021766208e-19; double const Class_physics::ELEMENTARY_CHARGE_ERROR = 0.0000000098e-19; double const Class_physics::GAS_CONSTANT = 8.3144598; double const Class_physics::GAS_CONSTANT_ERROR = 0.0000048; double const Class_physics::GRAVITATIONAL_CONSTANT = 6.693e-11; double const Class_physics::GRAVITATIONAL_CONSTANT_ERROR = 0.034e-11; double const Class_physics::NEUTRON_MASS = 1.674927471e-27; double const Class_physics::NEUTRON_MASS_ERROR = 0.000000021e-27;
All of these constants can be accessed by any functions in files that include "Class_physics.h" and the user can access these through, for example, Class_physics::GAS_CONSTANT.
1.