In this blog post, you will learn the static member function and its uses in C++ programming. Including the static member function, we also discuss the static member data (static member variable).
But before starting this blog post let’s first understand the requirement of static member function and variable in C++. It will help you in understanding static members in C++.
So, let’s discuss the requirement, during the programming sometimes we want to share a block memory with all objects.
This requirement accomplishes using the global variable but you know that the global variable is not much safer its value can be modified by anyone in the program. Personally, I don’t like the global variable.
So Now question is that if we don’t want to use global variables then how we can solve this problem?
Don’t worry C++ has a solution to this problem. The name of the solution is “static members”. Classes can contain static member data and static member functions. If you qualified a member with a static specifier, then only one copy of the member is maintained for all objects of the class.
The static members of the class are not bound to class instances. It is the reason; it is not necessary to use the class member access syntax to refer to a static member. A static member var of class Test also referred to using the qualified-id expression Test::var.
Static members of a class are not bound to any specific object instance. For this reason, it is not necessary to access them through an object. A static member variable of class Test can be accessed using the qualified-id expression Test::var.
struct Test
{
static const int var = 10;
};
int main()
{
cout << Test::var;
return 0;
}
What is static in C++?
In C++, the static keyword controls the lifetime, ownership, and visibility of variables and functions. When used inside a class, static changes how a member is stored and accessed in memory.
Unlike normal class members, static members belong to the class itself, not to individual objects created from that class.
Key Idea:
- Class-Level Ownership: Static members belong to the class itself, not to individual objects (instances).
- Shared Memory: Only one copy of a static variable exists in memory, regardless of how many objects you create. All objects share this single instance.
- Lifetime: Static variables retain their value for the entire runtime of the program (Static Storage Duration).
- Independence: Static functions can be called using the class name (e.g., Class::Function()) without ever creating an object.
- Restriction: Because static functions are independent of specific objects, they cannot access non-static variables or use the “this pointer“.
Note: Static members belong to the class, are shared by all objects, and live for the whole program.
Static Variable in C++:
A static variable in C++ is a class data member declared using the static keyword.
Unlike regular data members, a static data member belongs to the class itself, not to individual objects. This means only one copy of the variable exists in memory, and it is shared among all instances of the class.
Consider the below example,
class X
{
//data is static member variable
static int data;
};
Important points related to static data members:
The following are some important points related to static data members.
1. Static members of a class are not bound to individual instances. They belong to the class itself, not to any specific object. This means a static member is shared by all objects of the class, and only one copy exists in memory, regardless of how many objects are created.
2.Static members obey the usual class member access rules. So private access to static data members is allowed only for class-member functions and friends
3.Static member variable can be referred to using the qualified-id expression Class_Name::Attribute_Name.
4. A static data member is not part of individual objects of a class. Instead, it belongs to the class itself. Because of this, declaring a static data member inside the class does not allocate memory. The declaration only tells the compiler that the variable exists. Therefore, a static data member must be defined outside the class, usually in a source (.cpp) file, so that memory is actually allocated.
#include "iostream"
using namespace std;
class X
{
public:
static int data; // Declaration only
};
int main()
{
cout << X::data;
return 0;
}
Output:

You can see we are getting a linker error.
I believe you are thinking that why the linker error is coming and how we can resolve it.
I am dividing your answer in two categories first why linker error is coming and second how we can resolve it.
So the answer to your first question is that the declaration of a non-inline static data member in its class definition is not a definition. It is the reason the linker is unable to find the definition of “data” and throws the error.
Now the answer to your second question is that you can resolve the linker error by defining the static member variable. The syntax is following,
int X::data = 10; // definition
The static keyword is only used with the declaration of a static member but not with its definition.
🧠 Key Takeaway
- Inside class → declaration
- Outside class → definition + memory allocation
This rule ensures that only one shared copy of the static data member exists for the entire class.
5. Once the static data member has been defined, it exists even if no objects of its class have been created.
#include "iostream"
using namespace std;
class X
{
public:
static int data; // Declaration only
};
// Definition (memory allocation)
int X::data =10;
int main()
{
//data exist without the object
cout << X::data;
return 0;
}
Output: 10
6. We can not use mutable keywords with a static data member.
7.If a static data member is not declared thread_local there is one copy of the data member that is shared by all the objects of the class. The following example illustrates this:
#include "iostream"
using namespace std;
class X
{
public:
static int data;
};
int X::data =10;
int main()
{
X obj1, obj2;
//display value of data using obj1
cout << obj1.data<<endl;
//change value data using obj1
obj1.data = 12;
//display value of data using obj2
cout << obj2.data;
return 0;
}
Output: 10 12
8. If a static data member is declared thread_local there is one copy of the member per thread.
9. If a non-volatile non-inline const static data member is of integral or enumeration type, then it can be initialized with an initializer in which every expression is a constant expression.
class Y
{
public:
const static int a = 1;
const static int b{2}; // since C++11
const static int c;
};
const int Y::c = 3;
10.The inline and static keywords can use together for a data member. An inline static data member can be defined in the class definition and may specify an initializer. It does not need an out-of-class definition (C++17).
class Y
{
public:
//inline with static
inline static int n = 10;
};
11. There should be one definition for a static data member in C++.
Real-life examples of static data members in C++:
Let’s explore a few practical, real-world use cases of static data members in C++ with clear examples.
Static Data Members as a Safer Alternative to Macros:
One of the best uses of static data members is to represent constant values that are shared across a class. Traditionally, developers used macros (#define) for constants.
However, macros:
- Have no type safety.
- Ignore scope.
- Are hard to debug.
Static data members provide a safer and cleaner alternative to macros by keeping constants inside the class scope.
Let’s see an example to understand how static member variable work in C++.
#include <iostream>
using namespace std;
class Y
{
public:
const int length = 10;
};
int main()
{
Y obj1, obj2;
//display value of length using obj1
cout << obj1.length<<endl;
//display value of length using obj2
cout << obj2.length;
return 0;
}
The above class Y has a constant integral attribute “length”. The value of the length will be the same for each attribute and it will not change by any object.

The issue with the “length” attribute is that it consumes the memory for each object. I believe it is unnecessary and it becomes worse if the class has multiple objects and its uses by the less memory MCU.
We can resolve the memory wastage issue with the static keyword. It allows the creation of only a single copy of the “length” data member.
#include <iostream>
using namespace std;
class Y
{
public:
static const int length = 10;
};
int main()
{
Y obj1, obj2;
//display value of length using obj1
cout << obj1.length<<endl;
//display value of length using obj2
cout << obj2.length;
return 0;
}

Object Counter (Most Common Use Case):
A static data member can be used to count how many objects of a class have been created.
Real-Life Analogy:
A factory maintains one global counter to track the total number of products manufactured, regardless of how many production lines are running.
class Product
{
public:
static int totalProducts; // Shared counter for all objects
Product()
{
totalProducts++; // Increment whenever a new object is created
}
};
// Definition of the static data member
int Product::totalProducts = 0;
All Product objects share the same totalProducts variable, allowing it to accurately track the total number of objects created across the entire codebase.
Shared Configuration Setting
A static data member is ideal for storing configuration values that must be shared across the entire application, rather than duplicated for each object.
Example: Maximum Allowed Login Attempts
class SystemConfig
{
public:
static int maxLoginAttempts;
};
// Definition
int SystemConfig::maxLoginAttempts = 3;
Explanation:
- maxLoginAttempts belongs to the class, not to any specific object.
- Only one copy of this variable exists in memory.
- All parts of the application access the same value using:
SystemConfig::maxLoginAttempts
Hardware Resource Tracking:
In embedded systems, hardware peripherals such as UART, SPI, or I²C are limited resources. A robust firmware design must ensure that these resources are tracked safely and automatically.
A professional approach uses a static data member combined with RAII (Resource Acquisition Is Initialization). The hardware resource is acquired when an object is created and released when the object goes out of scope.
Example: UART Resource Tracking,
class UARTDriver
{
private:
static int activeUARTs; // Shared across all instances
static const int MAX_UARTS = 3; // Hardware limit
public:
UARTDriver()
{
if (activeUARTs < MAX_UARTS)
{
activeUARTs++;
// UART hardware initialization code
}
else
{
// Handle error: UART resource not available
}
}
~UARTDriver()
{
if (activeUARTs > 0)
{
activeUARTs--;
// UART hardware de-initialization code
}
}
static int getActiveCount()
{
return activeUARTs; // Read-only access
}
};
// Static member definition
int UARTDriver::activeUARTs = 0;
Code Explanation:
- static int activeUARTs → One shared variable tracks all active UART peripherals.
- MAX_UARTS → Ensures the firmware never exceeds the MCU’s UART limit.
- Constructor → Acquires a UART resource and increments the counter.
- Destructor → Releases the UART resource and decrements the counter automatically.
- getActiveCount() → Provides safe, read-only access to the UART usage count
Some valid data members of C++:
class ExampleClass
{
static int Expirydate; // No error
enum Ecolor {Mango = 0, Aplle, red}; // No error
int Data; // No error
//error only const static member initialized in class
static int Year = 1991;
const static int value = 12; // No error
const static int Sec =60; // No error
//inline with static
inline static int n = 10; //c++17
};
int ExampleClass::Expirydate = 918;
Static member function:
Like the static data member, we can also create static member functions. Consider the below example,
class X
{
public:
//foo is static member function
static void foo()
{
std::cout<<"I am static member function";
}
};
Important points related to static member functions:
The following are some important points related to static member functions.
1.Static member functions of the class are not bound to class instances.
2.Static member functions obey the usual class member access rules. So private access to a static member function is allowed only for class-member functions and friends.
3.Static member functions can be referred to using the qualified-id expression Class_Name::Static_Member_Function_Name. It means static member functions are not associated with any object.
#include<iostream>
class X
{
public:
//foo is static member function
static void foo()
{
std::cout<<"I am static member function";
}
};
int main()
{
//function calling without object
X::foo();
return 0;
}
Output:
I am static member function
4.A static member function does not have this pointer. Now you are thinking why; the reason is very simple static member functions are not associated with any object, so they don’t have this pointer. The following example illustrates this:
#include<iostream>
class X
{
const static int data = 10;
public:
//foo is static member function
static void foo()
{
//Use this pointer;
std::cout<<this->data;
}
};
int main()
{
//function calling without object
X::foo();
return 0;
}
Output: error: ‘this’ is unavailable for static member functions.
5.A static member function cannot be qualified with const, volatile, virtual, or ref-qualified. Consider the below example,

6.You cannot overload a static and non-static member function that has the same name and the same parameter types. The following example illustrates the same.
#include<iostream>
class X
{
public:
//foo is static member function
static void foo()
{
std::cout<<"I am static member function";
}
void foo()
{
std::cout<<"I am non-static member function";
}
};
int main()
{
return 0;
}
Output: error: ‘void X::foo()’ cannot be overloaded
7.The address of a static member function may be stored in a regular pointer to function, but not in a pointer to member function. The following example illustrates the same.
Example-1:
Pointer to member function with non-static member function.
#include<iostream>
struct X
{
void foo()
{
std::cout << "I am non-static member function\n";
}
};
int main()
{
// pointer to member function foo of class X
void (X::* fptr)() = &X::foo;
//object of X
X obj;
//calling member function
(obj.*fptr)();
return 0;
}
Output: I am non-static member function
Example-2:
Pointer to member function with static member function.
#include<iostream>
struct X
{
//static member function
static void foo()
{
std::cout << "I am non-static member function\n";
}
};
int main()
{
// pointer to member function foo of class X
void (X::* fptr)() = &X::foo;
//object of X
X obj;
//calling member function
(obj.*fptr)();
return 0;
}
Output: error: cannot convert ‘void (*)()’ to ‘void (X::*)()’ in initialization
Note: The type of “pointer-to-member-function” is different from “pointer-to-function”.
Use of static member function in C++:
There are many uses of static member functions but here we will discuss a few of them.
Accessing private static data member:
The static data member can be accessed without creating the instance but as you know that it obeys the class rule. The private static data member is only accessed by the class-member functions and friends.
If you will try to access the private static member function, you will get the compiler error. The following example illustrates the same.
#include<iostream>
class X
{
//private static member
static int t;
};
int X::t = 3;
int main()
{
X::t;
return 0;
}
Output: error: ‘int X::t’ is private
The above code is throwing the error because we breaking the class rule. We can easily solve this problem using the static member function
#include<iostream>
class X
{
static int t;
public:
//static member function
static void foo()
{
std::cout << t <<std::endl;
}
};
int X::t = 3;
int main()
{
X::foo();
return 0;
}
Output: 3
Meta-programming:
The static member functions are very good for template meta-programming. The template std::char_traits is a very good example. All member functions are static.
✌Click to solve Quiz on static members.
Recommended Articles for you:
- C++ Programming Courses And Tutorials
- Operator Overloading in C++ with some FAQ.
- MCQs on static members in C++.
- this pointer in C++ programming with some example code
- Amazing list of Gifts for Programmers, You must.
- Operator Overloading in C++ with some FAQ.
- Introduction of reference in C++.
- A brief introduction of pointers.
- Difference between pointers and references.
- Use of mutable keywords in C++.
- Best electronic kits for programmers.
- References and const in C++ with example programs.
- C++ Interview Questions with Answers.
- List of some Best C++ Books, you must see.
