Skip to content

Last updated:2026-10-12

C++ static Members and Lifetime

About the Author

WeChat official account:

wechat

The static keyword has different meanings when used with different things. We can use the static keyword for:

Static variables: variables in a function, variables in a class

Static class members: class objects and functions in a class

Now let's look at each of these uses of static in detail:

Static Variables

  • Static variables in a function

When a variable is declared as static, space for it is allocated for the lifetime of the program. Even if the function is called many times, space for the static variable is allocated only once, and the variable's value from the previous call carries over to the next call. This is very useful in C / C++ or any other application that needs to store the previous state of a function.

#include <iostream> 
#include <string> 
using namespace std; 

void demo() 
{ 
    // static variable 
    static int count = 0; 
    cout << count << " "; 

    // value is updated and 
    // will be carried to next 
    // function calls 
    count++; 
} 

int main() 
{ 
    for (int i=0; i<5; i++)  
        demo(); 
    return 0; 
} 

Output:

0 1 2 3 4 

You can see in the program above that the variable count is declared as static. Consequently, its value carries over across function calls. Each time the function is called, the counter variable is not re-initialized.

  • Static variables in a class

Because variables declared as static are initialized only once — they are allocated space in separate static storage — static variables in a class are shared by the objects. There cannot be multiple copies of the same static variable for different objects. For the same reason, a static variable cannot be initialized using a constructor.

#include<iostream> 
using namespace std; 

class Apple 
{ 
public: 
    static int i; 

    Apple() 
    { 
        // Do nothing 
    }; 
}; 

int main() 
{ 
Apple obj1; 
Apple obj2; 
obj1.i =2; 
obj2.i = 3; 

// prints value of i 
cout << obj1.i<<" "<<obj2.i; 
} 

You can see in the program above that we tried to create multiple copies of the static variable i for multiple objects. But that does not happen. Therefore, a static variable in a class should be explicitly initialized by the user outside the class, using the class name and the scope resolution operator, like this:

#include<iostream> 
using namespace std; 

class Apple 
{ 
public: 
    static int i; 

    Apple() 
    { 
        // Do nothing 
    }; 
}; 

int Apple::i = 1; 

int main() 
{ 
    Apple obj; 
    // prints value of i 
    cout << obj.i; 
} 

Output:

1

Static Members

  • Static class objects

Just like variables, objects declared as static also have a scope that lasts until the end of the program's lifetime.

Consider the following program, where the object is non-static.

#include<iostream> 
using namespace std; 

class Apple 
{ 
    int i; 
    public: 
        Apple() 
        { 
            i = 0; 
            cout << "Inside Constructor\n"; 
        } 
        ~Apple() 
        { 
            cout << "Inside Destructor\n"; 
        } 
}; 

int main() 
{ 
    int x = 0; 
    if (x==0) 
    { 
        Apple obj; 
    } 
    cout << "End of main\n"; 
} 

Output:

Inside Constructor
Inside Destructor
End of main

In the program above, the object is declared non-static inside the if block. Hence, the variable's scope is only within the if block. So when the object is created, the constructor is called, and the destructor is called at the same time the control of the if block passes beyond it, because the object's scope is only inside the if block where it is declared. If we declare the object as static, let's see how the output changes.

#include<iostream> 
using namespace std; 

class Apple 
{ 
    int i; 
    public: 
        Apple() 
        { 
            i = 0; 
            cout << "Inside Constructor\n"; 
        } 
        ~Apple() 
        { 
            cout << "Inside Destructor\n"; 
        } 
}; 

int main() 
{ 
    int x = 0; 
    if (x==0) 
    { 
        static Apple obj; 
    } 
    cout << "End of main\n"; 
} 

Output:

Inside Constructor
End of main
Inside Destructor

You can clearly see the change in the output. Now the destructor is called after the end of main. This is because a static object's scope spans the entire lifetime of the program.

  • Static functions in a class

Just like static data members or static variables in a class, static member functions do not depend on an object of the class. We are allowed to invoke a static member function using an object and the '.' operator. But it is recommended to invoke static members using the class name and the scope resolution operator.

Static member functions are allowed to access only static data members or other static member functions; they cannot access the class's non-static data members or member functions.

#include<iostream> 
using namespace std; 

class Apple 
{ 
    public: 
        // static member function 
        static void printMsg() 
        {
            cout<<"Welcome to Apple!"; 
        }
}; 

// main function 
int main() 
{ 
    // invoking a static member function 
    Apple::printMsg(); 
} 

Output:

Welcome to Apple!

Restricting Visibility

static also serves to restrict visibility (similar to an anonymous namespace). From issue: https://github.com/Light-City/CPlusPlusThings/issues/142

// source1.cpp
extern void sayHello();
const char* msg = "Hello World!\n";
int main()
{
    sayHello();
    return 0;
}

// source2.cpp
#include <cstdio>
extern char* msg;
void sayHello()
{
    printf("%s", msg);
}
g++ compiles the two files above just fine and prints Hello World!, but if you add static to msg in source1.cpp, you get an "undefined reference to 'msg'" link error:
// source1.cpp
extern void sayHello();
static const char* msg = "Hello World!\n";
int main()
{
    sayHello();
    return 0;
}

Comments