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 simply telling the class that a static member variable exists (much like a forward declaration). Because static member variables are not part of the individual class objects (they 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 is one exception where a static member definition line is not required: when the static member is of type const integer or const enum. Those can be initialized directly on the line in which they are declared:

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

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

59 comments to 8.11 — Static member variables

  • Dorian

    What could be the reason that they defined the static variable behaviour in a class so different than for a function?
    What could be against defining a static variable in a class, and initialialize it the first time a instance of that class is created (analog to call a function the first time, where a static variable gets initilized, and later calls dont reinitialize it).
    The pro would be that it completely belongs to a class (insted a messy declaration outside).

    • Alex

      Bjarne Stroustrup said, “A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.”

      In other words, static members need to be declared outside the class to ensure that there isn’t more than one definition for the static member. Functions don’t really have this problem.

  • Chris


    Hi Alex,

    the result of the code above is weird for me, because i think the result will be:
    because varible x is assign by 5 when i call foo function, and that is weird variable x is back to early value which is 2.

    and why that const member function can change value of static member variable?

    • Alex

      Const member functions guarantee they won’t change the state of the object. Static members are excluded, because they do not belong to the object.

      As for your other question, the results are undefined. You’re breaking the rule to not use any variables that have side effects applied more than once in an expression.

  • Rob G.

    Alex, hi. A small mystery to me here. I get an error as such:\src\main.cpp:9:17: error: ISO C++ forbids in-class initialization of non-const static member ‘Test::x’
    But if I make the expression that is static int x = 99 in the first code snippet const static int x = 99, it compiles and runs fine. Why is this?

    doesn’t work:

    works with addition of const:

    • Alex

      Bjarne Stroustrup says, “A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.”

      Static const integers (and enums) can be treated as compile-time constants, so the compiler can replace calls to the const integer with the value itself.

      • Sivasankar

        Hi Alex, Please make me correct. "C++ requires that every object has a unique definition" implies that the class definition should not be different for all objects of the particular class. i.e. each and every class object should have same class definition. Am I correct? Please confirm

        • Alex

          If you were able to initialize a static in the class definition, then when you #included that class into multiple files, the static variable definition (with initializer) would be included into multiple files too. The linker would have a hard time determining what to do in this case. By forcing you to choose which code file the definition (and initializer) go into, this issue is circumvented.

          Why he uses the word “unique” in this case, I’m not sure.

  • Mauricio Mirabetti

    Alex, found a small typo:
    "…first.m_nValue is distinct from second.m_nValue." <- should be m_value.



  • subh samal

    class Something
        int m_value = 1;

    int main()
        Something first;
        Something second;
        second.m_value = 2;

        std::cout << first.m_value << ‘\n’;
        std::cout << second.m_value << ‘\n’;

        return 0;
    }   ( output 2, 2 )

    I followed the the above program (initialization of static variable through object,  second.m_value = 2;) and tried initialization of static variable in the below program:

    #include <iostream>

    class Something
        static int s_idGenerator;
        int m_id;

        Something() { m_id = s_idGenerator++; } // grab the next value from the id generator

        int getID() const { return m_id; }

    // Note that we’re defining and initializing s_idGenerator even though it is declared as private above.
    // This is okay since the definition isn’t subject to access controls.
    int Something::s_idGenerator = 1; // start our ID generator with value 1

    int main()
        Something first;
        Something second;
        second.s_idGenerator = 5; // initialized the static variable through object
        Something third;

        std::cout << first.getID() << ‘\n’;
        std::cout << second.getID() << ‘\n’;
        std::cout << third.getID() << ‘\n’;
        return 0;

    (output 1,2,5) I was expecting the output to be 5,5,5: just as in case of 1st program it is 2,2.
    I am able to differentiate that in the first case it is public while in second case it is private, but this does not make me understand.

    • Alex

      A few things:
      First, the top program prints 1, 2.

      Second, in the bottom program, you’ve declared s_idGenerator as private, so this line should fail to compile:

      However, let’s set it to public just for the sake of example.
      When first is created, s_idGenerator is 1, so first.m_id is set to 1.
      When second is created, s_idGenerator is 2, so second.m_id is set to 2.
      Then you set s_idGenerator to 5.
      When third is created, s_idGenerator is 5, so third.m_id is set to 5.

      That’s why you get 1, 2, and 5 as your answer.

  • Squalus

    Note that even if you are able to initialize "static const integers or const enums" in declaration, that doesn’t mean they are defined (try getting address or creating reference to it). The reason why you can initialize "static const integers" right in declaration(directly in class) is that they can be then used as compile-time constants (for stuff like declaring array (size has to be compile-time constant)). This also means that if you are initializing "static const integers" in declaration, you have to initialize it with another compile-time constant. As I said above if variable is initialized in declaration it doesn’t mean it is also defined. Because of that, you can use this variable only as (r)value (you can`t create reference from it, it doesn’t have address, and other stuff where lvalue is needed). Also if it is only declared you can`t access it from other files.

    If you also define this "static const integer" , you can use this as normal variable (creating references, it now has address, etc. ).
    So here:

    if we add this:

    It will make huge difference.
    More here: []
    (I think third answer is the best)


    • Squalus

      Sorry, I forgot to mention one important fact: If compiler wants to use compile-time constant it has to see it (see its declaration) in every translation unit(source code with it`s all included header files) where it is used. So if you want to use "static const integer" as compile-time constant you declare it in class`s header file and it can be used wherever that header file of this class is included.

  • please tell me why static id.this program show me values 5,5,5,5,5
    1,2,3,4,5 we want this values
    tell me

    using namespace std;
    class student{
            static int id;
            char name[10];
                cout<<"enter the name:";
                void show()
                    cout<<"id is "<<id<<endl;
                    cout<<"name is  "<<name<<endl;;
    int student::id=1;
    int main()

        student obj[5];
        for(int i=0;i<5;i++)


    • Alex

      static int id is shared by all objects of the class. And your class constructor is incrementing this shared value. Therefore, every time you create an instance of the class, id will get incremented.

      Assuming that id starts at 0, if you create 5 students, you’re incrementing id 5 times, therefore it should have the value 5.

      Also, in the example above, id is uninitialized. You should give it an initializer.

  • GeekPro

    What are the real time example/ usage of static variables and member functions?

  • Xi Yin

    Hi Alex,

    Thank you for the wonderful tutorial. I have been following it for a week and everything that I used to confuse about just makes more sense now.

    I have a question regarding the last example.

    Since the objects are all non const and the function GetID() is const.  why is it legal to call a const function with a non-const object, but not the other way round?

    I tried a few things:
    - remove the const in the function definition, -> it still works
    - add const to all objects -> it works
    - do both the above -> it does not work.


    • Alex

      A non-const object is one that can be modified. A const object is one that can’t be modified.

      A non-const function may modify the object it’s called on. A const function guarantees it won’t modify the object called on.

      Therefore, a const object can only use const functions, because non-const functions could potentially modify the object, which the constness of the object won’t allow.

      However, non-const objects don’t care if they get modified, so they can use both const and non-const functions.

  • One more question, why we can’t initialize that member variable using the scope operator inside a function?

    This is an error:

  • I was wondering why the data type is required when initializing the static member variable. We already declared the variable as int in the class declaration. If I leave the data type that is int in this case, the compiler throws an error, why? We are telling the compiler from where to pick (using :: operator) and also what to pick (using the identifier). Shouldn’t the compiler know what’s the data type of that variable?

    • Alex

      I don’t know for sure. But two things come to mind:
      1) All definitions in C++ require types, and this is no exception.
      2) If it didn’t have a type, it would be dependent on a declaration having been previously seen, which could cause ordering issues.

  • Michael

    Last example:

    why is there a ‘const’ here:


    • Alex

      That const means GetD() is guaranteed not to modify the object it’s associated with.

      Besides being a generally good programming practice, it also allows GetID() to be called with a const object of type Something.

  • Mohammad Erfan

    class Test
    int x,y;
    static Test def;
    Test(int x=-1;int y=-1)
    static void setTest(int xx,int yy);

    My question is how can I set def value of Test.

    • Alex

      Add the following line outside of the class:

      Your constructor is pretty messed up though. You’ll need to fix it before this will work.

  • Dan

    Great website!
    One question - does it matter where exactly in the file the static member variable is initialised? For example, will it be initialised before int main() even if it is defined afterwards in the code?

    • Alex

      It doesn’t matter where it’s defined, so long as it’s defined once and only once. The class definition serves as a forward declaration, so it can be used from anywhere that can see the class declaration, and the linker will resolve it.

  • Chris_M


    In the last paragraph of this section, you mention an internal lookup table. Are there any examples on this site on how to implement an internal lookup table? Thank you.

  • ashly

    like static member variables , static member functions , is static class itself possible in c++?

    • Alex

      No, C++ does not currently directly support applying the static keyword to classes.

      The nearest thing is a class with only static variables and static functions.

  • Ashish79

    Can we call non-static functions with static objects?

  • Poke

    Hello! I’m having an issue with a static member variable…my g++ compiler is giving me the error: undefined reference to `ShipType::m_format’. Nearly all of the comments I’ve read say to instantiate the static outside the class, which I have done. Here’s my code snippet:

    Thank you in advance…


    • D.M. Ryan

      Did you try changing



      In the examples above, the class scope isn’t added when a static variable is declared within the class itself.

      That fix may not work, but it’s worth a try.

      is correct.

    • Alex

      Type, variable name (with class and scope resolution operator), and initializer.

  • Dawid Chemloul

    I have questions and maybe some answers.

    1. Is static in function variable guaranteed to be initialized (created) at first function call or is it compiler dependent?

    as for singletons - it is possible to use static member to create singleton with nice encapsulation but I would rather use static variable in function if answer for my first question is yes.

    Since if you will try make some static singleton objects - or some static objects using your singletons then initialisation order of all those global static globals need to be maintained with care.

    Since it is possible that you will create a singleton instance before global member was initialised - then initialisation of global member will override previous usage… this seamnot to pose problems used this way in VS2010


    • Alex

      Local static variables are initialized the first time the definition line is encountered. Global static variables and static member functions are initialized at program startup.

  • davidv

    I have 2 questions.
    First: in the last example, s_nIDGenerator was declared as a private member, but was accessed outside the class. I compiled the code, and it works. How come we didn’t run into trouble?
    Second: the name convention for static member does not reflect membership. Wouldn’t something like ms_nName be better than s_nName?
    Thank you.

    • luke

      First: This is from Schildt’s “The Complete Reference: C++ 4th ed.”
      When you declare a static data me3mber within a class, you are not defining it. (That is, you are not allocating storage for it.) Instead, you must provide a global definition for it elsewhere, outside the class.
      You’re not accessing a private variable, but rather defining it. This also sheds some (more) light on Renu’s question.

      Second: Are you serious? I’m pretty sure Alex put the ‘s’ and ‘m’ prefixes there to distinguish between static and member. ‘s’ is definitely easier to distinguish from ‘m’ than “ms”. Let’s not forget these are examples. I’m surprised you didn’t comment on “Something” not being a very good class name.

    • Darren

      Did Luke and David ever bury the hatchet and make-up? It seems we’ll never know - the show seems to have got the chop back in 2008 after one episode. 🙁

  • Zafer

    Two questions. In the last coding example, why didn’t we declare the objects cFirst, cSecond and cThird as const objects since we are using the GetId function, which has const in its declaration? My second question is about the static keyword. In the explanation provided after the last example, it says: “This guarantees that each Something object receives a unique id (incremented in the order of creation).” However since there is only one copy of the static variable and as we increment it, the id values of cFirst, cSecond and cThird will all be the same instead of being unique. This part needs to be clarified.

    • cFirst, cSecond, and cThird could be declared as const objects since they only call GetID(), which is const.

      The basic idea here is that there is only one copy of s_nIDGenerator that is shared amongst all of the objects of type Something. However, each individual object has it’s own m_nID value that is not shared.

      When we construct a new Something, the Something constructor copies the current value of s_nIDGenerator into the not-shared m_nID and then increments it. Keep in mind that when we increment s_nIDGenerator, this does not affect any of the m_nID values that have already been assigned!

      So let’s look at what happens in more detail. First, s_nIDGenerator is set to 1.

      At this point we have:
      s_nIDGenerator = 1

      Then, we construct cFirst. cFirst’s constructor copies the value of s_nIDGenerator (1) into cFirst.m_nID and then increments s_nIDGenerator to 2.

      At this point we have:
      cFirst.m_nID = 1
      s_nIDGenerator = 2

      Then, we construct cSecond. cSecond’s constructor copies the value of s_nIDGenerator (2) into cSecond.m_nID, and then increments s_nIDGenerator to 3.

      At this point we have:
      cFirst.m_nID = 1
      cSecond.m_nID = 2
      s_nIDGenerator = 3

      Finally, we construct cThird. This proceeds in the same way as the previous constructors.

      At this point we have:
      cFirst.m_nID = 1
      cSecond.m_nID = 2
      cThird.m_nID = 3
      s_nIDGenerator = 4

      Note that s_nIDGenerator is not used any more. It is only used to set the initial value of m_nID. If we ask a Something object for it’s ID, it always returns it’s non-shared m_nID value.

      • Dominick

        I am having a hard time understand how s_idGenerator is being incremented:

        This is the line that is incrementing s_idGenerator? How is it both defining m_id and
        incrementing s_idGenerator at the same time? I have never seen that done before.

        From my understanding s_idGenerator would be the equivalent to 1 + 1. Yet, the way it’s used
        here looks like two separate lines of code in one, for example:

  • Renu

    static int s_nValue; ……
    int Something::s_nValue = 1;

    Why is “int” used in initialising
    Something::s_nValue = 1

    We have already declared s_nValue as static int in class definition. What is the purpose of using
    int again in
    ” int Something::s_nValue = 1; ” ?


    • This is a good question, and I am not sure of the answer. Because static members belong to the class, not objects of the class, I presume the declaration in the class is essentially treated as a forward declaration of the static member, which is actually defined in the body of the code. Thus, much like forward declarations for functions, which need to have the return type and parameter types in both the forward declaration and the actual definition, this would adhere to the same rules.

      • Dayu

        I tried the third code without the line

        . i.e.

        I got a compilation error:

        …/main.cpp|15|undefined reference to `Something::s_nValue’|.

        I also tried

        Note that there is no “=1” this time, and everything works out fine with s_nValue=0;
        Does this mean

        is always needed when we declare a static variable of a class? By the way, I am using Code::Blocks with GCC as the compiler on my Ubuntu.

        • Static member variables always need to be defined in the code file. The fact that

          happened to evaluate to 0 was probably circumstantial in the same way that

          will probably be 0, but it’s not guaranteed.

          • Topjob

            Alex, then what did you mean by:

            “In the absense of an initializing line, C++ will initialize the value to 0.”?

          • dog44wgm

            Definitely 0 according to the Standard (draft 2011):

            “Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5)
            before any other initialization takes place”.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter