Just like static members variables, static methods are also a thing. They can be called directly using ::.
Calling a static method through the class
Since static methods belong to the class they can be called directly.
#include <iostream>
#include <utility>
class BatteryMonitorConfig {
private:
static inline int s_samplePeriodMs { 1000 };
static inline std::pair s_safeVoltageRange { 3.0, 4.2 };
public:
static int samplePeriodMs(){
return s_samplePeriodMs;
}
static bool isVoltageSafe(double voltage){
return voltage >= s_safeVoltageRange.first
&& voltage <= s_safeVoltageRange.second;
}
};
int main(){
std::cout << "Sample period: "
<< BatteryMonitorConfig::samplePeriodMs() << " ms\n";
std::cout << std::boolalpha;
std::cout << "3.7 V safe: "
<< BatteryMonitorConfig::isVoltageSafe(3.7) << '\n';
std::cout << "4.6 V safe: "
<< BatteryMonitorConfig::isVoltageSafe(4.6) << '\n';
}
Terminal output:
Sample period: 1000 ms
3.7 V safe: true
4.6 V safe: false
No BatteryMonitorConfig object is created.
The static methods are called directly through the class:
BatteryMonitorConfig::samplePeriodMs()
BatteryMonitorConfig::isVoltageSafe(3.7)
Accessors are easy candidates for static
Accessor methods should be assigned static since they belong to the class and not the class objects.
See the program below. A static method is used as a getter for a static member.
#include <iostream>
class Something
{
private:
static inline int s_value { 1 };
public:
// Static method
static int getValue() { return s_value; }
};
int main()
{
// We can call the static method without instantiating the class
std::cout << Something::getValue() << '\n';
}
Static member functions have no this pointer
Since static methods belong to the class, they have no this pointer. This makes sense as no object can hold a static method.
If a static method wishes to operate on private member variables, it must accept an object (i.e. use the public interface):
#include <iostream>
class Counter {
private:
int m_value {};
public:
explicit Counter(int value)
: m_value { value }
{
}
// Accepts a reference to a Counter object
static void reset(Counter& counter)
{
counter.m_value = 0;
}
void print() const
{
std::cout << m_value << '\n';
}
};
int main()
{
Counter counter { 42 };
Counter::reset(counter);
counter.print();
}
Terminal output:
0
The singleton pattern uses a static method
This makes sense since we only want one instance of an object which belongs to the class itself.
For example, in my text PRG, EventBus::Instance() is static:
// .h
static EventBus& Instance();
// .cpp
EventBus& EventBus::Instance() {
static EventBus instance;
return instance;
}
The motivation is to have a single Eventbus that is shared across the code base.
In Summary
- A static member function belongs to the class, not to one object.
- A static member function can be called with
ClassName::function(). - A static member function has no
thispointer.