Skip to content

Last updated:2026-10-13

C++ static Explained: Static Variables, Members and Functions

About the Author

WeChat official account:

C++ static Explained: Static Variables, Members and Functions | C++那些事

When used with different kinds of entities, the static keyword has different meanings. We can use the static keyword:

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 these uses of static in detail:

Static variables

  • Static variables in a function

When a variable is declared static, space is allocated for the lifetime of the program. Even if the function is called multiple times, space for the static variable is allocated only once, and the value of the variable from the previous call is carried over to the next function 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 static. Therefore, its value is carried across function calls. Each time the function is called, the count variable is not initialized again.

  • Static variables in a class

Since variables declared static are initialized only once — because they are allocated space in separate static storage — static variables in a class are shared by objects. There cannot be multiple copies of the same static variable for different objects. It is also for this reason that static variables 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 did 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, as follows:

#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

  • Class objects as static

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

Consider the following program, in which 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. Therefore, the variable's scope is only within the if block. Hence, when the object is created the constructor is called, and the destructor is called at the same moment the control of the if block passes it, because the object's scope is limited to the if block in which it is declared.

If we declare the object as static, let's now 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 the scope of a static object 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 objects of the class. We are allowed to invoke a static member function using an object and '.'. However, 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 the scope of access

static also serves to restrict the scope of access (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 code files above normally and prints Hello World!, but if you add static to msg in source1.cpp, it causes an 'undefined reference to msg' compilation error:

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

Internal Linkage of static (Restricting the Scope of Access)

Thanks to issue #142 for pointing this out: when static qualifies a global variable/function, it also serves to restrict the scope of access — it changes its linkage from external linkage to internal linkage, with an effect similar to an anonymous namespace:

  • A global variable that is not static: other translation units can access it through an extern declaration;
  • A static global variable/function: visible only within the current translation unit; even an extern declaration cannot link to it (undefined reference).

In modern C++ it is preferable to use an anonymous namespace to express "visible only in this file" (it also works for types), but understanding this aspect of static is very important when reading older code.

// file1.cpp
static int hidden = 42;          // 内部链接:其他文件 extern 不可见
int visible = 1;                 // 外部链接:其他文件可 extern 访问

namespace {                      // 匿名命名空间:等价且更现代的写法
    int also_hidden = 7;
}

FAQ

How does a static global differ from a normal global?

A static global has internal linkage: it is visible only inside its translation unit. A normal global is visible across files and prone to symbol clashes.

When is a static local variable initialized?

Once, the first time control passes its definition; since C++11 that initialization is thread-safe. Its lifetime lasts until the program ends.

Can a static member function access non-static members?

No. A static member function has no this pointer, so it can only touch static members.

Comments