The distinction between regular and static variables in C++ is a such a confusing topic for many beginners including students and programers. In this short article, I am going to provide an brief explanation and hopefully remove the ambiguity. I personally believe that the root cause of confusion is due to lack of context. To be more specific, a discussion involving variables without indicating variable scopes and memory layout is a fruitless discussion. With that said, let us set the ground first by reviewing some basic concepts.
In short, a scope is the program area where a defined variable can be accessed. In other words, it refers to the visibility of a variable. Based on that, we can roughly define two types of scopes (actually there are more than just two):
Local variable is defined inside a block of code such as a function. This means that the variable can only be accessed inside the function and is destroyed after the function call returns.
Global variable is defined outside all available functions and visible to all. The variable lives as long as the program is running.
Take a look at the code snippet below, it shows example local and global variable scopes
//g is global to the entire program and
//can be accessed every where including
//main and myFunc
int g = 10;
//x is local to myFunc and can only
//be accessed inside myFunc
int x = 5;
Depending on scope, variables are stored in specific memory segments. A typical Linux based operating system has the following logical memory layout:
Stack memory stores local variables (and other information ex. function parameters, return address). When a function is called, its local variables are pushed to the stack memory. These variables are removed as soon as the function finishes execution.
Data memory stores global variables and static variables (we will explain that later).
Heap memory is used for dynamic memory allocation at run time.
Text memory stores program code.
Static variable C++
So far so good, now we know what a variable scope is and where is it stored in memory. We are ready now to talk about static variables. In terms of scope, a static variable can be local to a function or even global however in either case it is stored in the data memory segment. Typically, a static variable is local to a function or class however it is NOT stored on the stack. In C++ to create a static variable we precede it with a static keyword. Let us now explore static variables based on scope.
Function static variable
Local static variables inside a function after initialization maintain their values even after the function call is finished. This is because they are permanently (until the end of the program) stored in the data segment. They are not stored on the stack like regular local variables otherwise they would have been destroyed after a function call returns. Why would we bother to use a static variable inside a function? a static variable inside a function is just like a global variable however it is only accessible inside the function. For example, we can use a local static variable to keep track of the number of times a function has been called. Here is how to do that:
//This line is only executed once regardless
//of how many times the function has been called
static int count = 0;
You can also use the same trick to prevent a variable from being reinitialized inside a nested loop. Take a look at the following example:
The variable count above is going to be 100 after the outer loop finishes because initialization happens only once. Let us move to the next location where a static variable can be:
Static data member in c++ definition
I assume you are familiar with the basics of object oriented programming but let us quickly review what a class is and what an object is. A class is a like a blueprint and an object is an instance. For example, a cube is a class and a particular cube with a given size and color is an object that belongs to that class. Classes do have member variables and methods or member functions. A regular class variable can have different values depending on which object we are referring to. On the other hand, static class member variables are the same for any object that belongs to the class. Think of static member variable as class level variable that is global to all objects or instances of the class. A static member variable provides information relevant to the making of new member objects. One simple example is to use a static member variable to keep track of the number of instances created so far. Here is an example code snippet:
Static data member in c++ simple example
//Define a class
//Declares a static data member variable
//to keep track of how many objects were created
static int count;
//Object number for example the fifth
//object created has number = 5
//Constructor of the class
//When a new object is instantiated
//increment the number of objects created
number = count++;
//Return object number
int getObjectNumber() const
//Initialize the class static member variable and make sure
//to initialize it outside myClass and inside a cpp file
//otherwise it will not be in scope.
int myClass::count = 1;
std::cout << mc1.getObjectNumber() << '\n';
std::cout << mc2.getObjectNumber() << '\n';
std::cout << mc3.getObjectNumber() << '\n';
If you execute the code above you will get 1, 2, 3 in the output console.
The count static data member above is private so we can not directly access it using myClass::count unless it is public. In order to do so we need to use an object public member function but this requires us to instantiate an object. That is not pretty as the private static data member is a class level variable. A nicer way is to use a static member function which is explained below:
Static member function
Static member function is not tied to any particular class instance just like static data members. For that reason: (1) you can not use “this” pointer inside a static member function (2) static member functions can only access static member variables. Take a look at the following example:
//Private static data member delaration
static int count;
//Public static member function
static int getCount()
//Initialize static data member
int myClass::count = 1;
std::cout << myClass::getCount() << '\n';
Summary - Characteristics of static data member in c++
I know it may sound overwhelming but if you take a deep breath it should be easy like a charm. My personal advise for understanding any confusing topic is to set a relevant context and divide the topic into smaller pieces like what we did in this post. Let us summarize the use of static data member in c++:
A variable has a scope which is the area of the program where the variable is visible and can be accessed.
Depending on scope, the variable can be stored in different segments of the main memory.
Local variables are pushed to the stack while global and static variables are stored in the data segment.
A static variable local to a function is similar to a global variable however it is only accessible from inside the function.
A static variable is initialized once and maintains its value during function calls and keeps alive as long as the program is running.
Similarly, a class can have static data members which are global to all objects that belong to the class and are only accessible from the instances of that class or by a static member function.
To mention a few easy to follow examples on using static variables (1) tracking information relevant to creating new objects of a particular class such as how many objects were created (2) how many times a function was called (3) preventing a nested loop from reinitialization.
I hope you liked the article and benefited as well. Please use the section below for questions and comments. Thanks for reading.