8.11 — Static member variables

Review of static keyword uses

In the lesson on file scope and the static keyword, you learned that static variables keep their values and are not destroyed even after they go out of scope. For example:

This program prints:


Note that s_id has kept its value across multiple function calls.

The static keyword has another meaning when applied to global variables -- it gives them internal linkage (which restricts them from being seen/used outside of the file they are defined in). Because global variables are typically avoided, the static keyword is not often used in this capacity.

Static member variables

C++ introduces two more uses for the static keyword when applied to classes: static member variables, and static member functions. Fortunately, these uses are fairly straightforward. We’ll talk about static member variables in this lesson, and static member functions in the next.

Before we go into the static keyword as applied to member variables, first consider the following class:

When we instantiate a class object, each object gets its own copy of all normal member variables. In this case, because we have declared two Something class objects, we end up with two copies of m_value: first.m_value, and second.m_value. first.m_value is distinct from second.m_value. Consequently, the program above prints:


Member variables of a class can be made static by using the static keyword. Unlike normal member variables, static member variables are shared by all objects of the class. Consider the following program, similar to the above:

This program produces the following output:


Because s_value is a static member variable, s_value is shared between all objects of the class. Consequently, first.s_value is the same variable as second.s_value. The above program shows that the value we set using first can be accessed using second!

Static members are not associated with class objects

Although you can access static members through objects of the class (as shown with first.s_value and second.s_value in the example above), it turns out that static members exist even if no objects of the class have been instantiated! Much like global variables, they are created when the program starts, and destroyed when the program ends.

Consequently, it is better to think of static members as belonging to the class itself, not to the objects of the class. Because s_value exists independently of any class objects, it can be accessed directly using the class name and the scope resolution operator (in this case, Something::s_value):

In the above snippet, s_value is referenced by class name rather than through an object. Note that we have not even instantiated an object of type Something, but we are still able to access and use Something::s_value. This is the preferred method for accessing static members.

Defining and initializing static member variables

When we declare a static member variable inside a class, we’re telling the compiler about the existence of a static member variable, but not actually defining it (much like a forward declaration). Because static member variables are not part of the individual class objects (they are treated similarly to global variables, and get initialized when the program starts), you must explicitly define the static member outside of the class, in the global scope.

In the example above, we do so via this line:

This line serves two purposes: it instantiates the static member variable (just like a global variable), and optionally initializes it. In this case, we’re providing the initialization value 1. If no initializer is provided, C++ initializes the value to 0.

Note that this static member definition is not subject to access controls: you can define and initialize the value even if it’s declared as private (or protected) in the class.

If the class is defined in a .h file, the static member definition is usually placed in the associated code file for the class (e.g. Something.cpp). If the class is defined in a .cpp file, the static member definition is usually placed directly underneath the class. Do not put the static member definition in a header file (much like a global variable, if that header file gets included more than once, you’ll end up with multiple definitions, which will cause a compile error).

Inline initialization of static member variables

There are a few shortcuts to the above. First, when the static member is a const integral type (which includes char and bool) or a const enum, the static member can be initialized inside the class definition:

In the above example, because the static member variable is a const int, no explicit definition line is needed.

Second, as of C++11, static constexpr members of any type that supports constexpr initialization can be initialized inside the class definition:

An example of static member variables

Why use static variables inside classes? One great example is to assign a unique ID to every instance of the class. Here’s an example of that:

This program prints:


Because s_idGenerator is shared by all Something objects, when a new Something object is created, the constructor grabs the current value out of s_idGenerator and then increments the value for the next object. This guarantees that each instantiated Something object receives a unique id (incremented in the order of creation). This can really help when debugging multiple items in an array, as it provides a way to tell multiple objects of the same class type apart!

Static member variables can also be useful when the class needs to utilize an internal lookup table (e.g. an array used to store a set of pre-calculated values). By making the lookup table static, only one copy exists for all objects, rather than making a copy for each object instantiated. This can save substantial amounts of memory.

8.12 -- Static member functions
8.10 -- Const class objects and member functions

123 comments to 8.11 — Static member variables

  • Phuc

    Hello !
    Why method (int getID() const { return m_id; }) is const But the object created is not const but it still calls the method const

  • Samira Ferdi

    Hi, Alex and Nascardriver!

    What do you mean 'copy'? I often very confuse about this term.

    • When multiple objects have the same value and will always have the same value, they're copies of each other.

  • mmp52

    Why do we use "int" declaration here? Don't we already have the definition of the static member variable when we define the class itself?

    I was expecting a direct assignment:

    • Alex

      No -- what's in the class (static int s_value) is a declaration.

      In order to be instantiated, the variable needs a definition. The top one is a definition. The bottom one is just a statement.

  • McDidda

    why definitions of static member function/variable (defined outside of class) doesn't have "static" keyword  used to define the function/variable?

    • Alex

      I'm actually not sure. Anybody else have any insights on why the definition/initializer doesn't require the static keyword?

      • The function definition cannot be ambiguous, ie. it can be uniquely resolved to its declaration, even without `static` at the definition. Just like `virtual` or default arguments, adding `static` to the definition would be redundant.

  • McDidda

    Could you please explain the reason for not defining/initializing static member s_value inside class Something, and instead defining it outside, but in case of const static member variable we define it inside class?

    • Alex

      If the static is a const integral value, the compiler can usually optimize it away. Otherwise, it needs to be defined outside the class because it's essentially a global variable, not tied to objects of the class.

      • Michael Djamoos

        Also, since the variable is essentially a global variable, you would not want each new object instantiation to initialize it again.

        • Alex

          While true, C++ handles this fine for local static variables, which can have an initializer, but are only initialized once despite the initializer being inside the function.

  • sekhar

    Hi Alex, Tutorials are amazing and leaned a lot, Thanks for these awesome tutorials.

    Have a question for below code snippet :

    Just need clarity if really makes sense to apply const to static member functions/objects in a class and why const can't be applied to static function even though it gets invoked with static const object ?

    • * Line 13, 3, 8: Initialize your variables with brace initializers.
      * Line 15, 26: Limit your lines to 80 characters in length for better readability on small displays.
      * Don't use "using namespace".

      static members aren't linked to an object. s.getstatic() is the same as Sample::getstatic().

      • sekhar

        Thanks nascardriver. Could you please let me know the reason why const can't be applied to static member functions ? Is there any particular reason that you can think of ?

        • There's no reason why this should be possible. They aren't members of an object, so the pseudo-object they're accessing can't be const, so they can always modify it and you can always call them.
          Marking those functions const would only help you to not accidentally modify any static members in a function where you didn't intend to. Just like marking pass-by-value arguments as const, this has no practical effect.

  • Matty J

    So let's say you build a class Monster, and nest a class Keese within it.
    Let's say you wanted Link's level (Zelda is now an RPG in this example) to scale the Keese's health
    You could write Monster::Keese::m_health += 1.2 * levelLink to scale all Keese (normal, fire, etc.) instead of each one individually

    This example is probably better with Oblivion, but I've already typed it

  • prabhu

    Hi Alex/Nascardriver,

    I have a question on inline initialization on static member variable.
    When we initialize like
    static int a; , we have to define the variable outside the class , and duration/scope of the variable will be persist till end of class and the static variable belong to class rather then object, so it will get updated every time its called through object or scope resolution operator. I am ok with the above points.

    if i define & declaration  like const int a =10 ;
    here I should initialize the content in the declaration itself since its const and it will not allow us to update the value of a .I am ok with the above points here also

    But If i declare and define like static const int a = 10 means ,
    what are the properties , it will take forward from static and const.

  • Udit

    The lookup table example could be:

  • Micah

    Why does it print backwards if you don't initialize a new std::cout call?
    output for this is:
    3 2

    • Hi Micah!

      The evaluation order of multiple << is undefined.

      • Micah

        Thanks, I see, then different statements guarantee evaluation order.
        Okay then a couple questions if you don't mind..
        If they are undefined in evaluation order, why do they evaluate backwards? Does the computer just have to assume how to print and evaluate with the operator? And if so, why does it assume the same way each time?
        Would that not be an update-able fix to reverse the process?
        And, is there another way to send multiple calls like this to the console on one line? Or is this just a qwerk of C++?

        • The compiler decides the evaluation order. Yours appears to evaluate the statement backwards. As long as you're using the same compiler, you'll get the same results.

          > Would that not be an update-able fix to reverse the process?
          Reversing the order is probably easy, but the c++ standard doesn't state a specific order, so there is no reason to choose one way over the other.

          > is there another way to send multiple calls like this to the console on one line?
          Store the values in temporaries before printing them

          The behavior of this code is the same across all compilers.

  • Aditi

    Thank you for the great examples . They were really easy to understand and explained the concept very well :)

  • Dr. Khalid Alharbi

    Hi Alex,

    I think static member definition and initialization is not subject to access controls,but static members that are under private section cannot be accessed directly using the class name or through objects of the class. We need to use static member functions to access (i.e., read and/or write) static data members.
    The following code works fine, but if you try to run the comments you will receive an error: ‘int Something::s_value’ is private within this context.

    #include <iostream>
    using namespace std;
    class Something
         static int getvalue()
             return s_value;
         static void setvalue()
          static int s_value;

    int Something::s_value=0 ;

    int main()
        Something first;
        Something second;

        //first.s_value = 2;
       // cout << first.s_value << '\n';
       //cout << second.s_value << '\n';
       //cout << Something::s_value << '\n';
       cout << Something::getvalue() << '\n';
        return 0;

  • Peter Baum

    The static member definition and initialization looks just like a global to me in terms of where it is defined and its function.  The only thing slightly different is that it is namespace qualified by the class name.  Is there anything else that differentiates it from an ordinary global?

  • April

    How is it that the first, second, and third objects can access the getId member function if it is const and the objects themselves are not?

    • nascardriver

      Hi April!

      Non-const objects can access const-functions (The object is allowed to be modified, the function doesn't modify anything, everything is fine).
      Const objects can't access non-const functions (The object is not allowed to be modified, the function wants to modify the object, not allowed).

  • Arnav Borborah

    You have written:

    "Second, as of C++11, static constexpr members of any type can be initialized inside the class definition:"

    Does this apply for classes without constexpr constructors? How would they be initialized at compile time? (I presume they won't since classes such as std::vector use runtime dynamic allocation)

    • nascardriver

      Hi Arnav!

      I'm not sure if I got your question right since what you wrote isn't related to your quote.

      The quote states that this is allowed

      What (I think) you asked is having a constexpr object of a type without a constexpr constructor

    • Alex

      constexpr variables aren't initialized at compile time (they are initialized at run-time). However, the value they are initialized with must be known at compile time.

      C++ doesn't currently support const (or constexpr) constructors in any case.

      • Arnav Borborah

        Alex, C++ actually [does support `constexpr` constructors]( (Scroll down a bit to see it).

        nascardriver, I'm asking that if I am allowed to do:

        When CNonConst does NOT have a constexpr constructor. I am confused about why it says "any type" when this is not allowed for classes without a constexpr constructor.

        • Alex

          1) I stand corrected!
          2) I see what you're getting at. I'll amend the text to be more specific that this applies only to types that can actually be created as constexpr.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]