Language Selector

8.11 — Static member variables

Static keyword in C

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_nID has kept it’s value across multiple function calls.

The static keyword has another meaning when applied to global variables -- it changes them from global scope to file scope. Because global variables are typically avoided by competent programmers, and file scope variables are just global variables limited to a single file, the static keyword is typically not used in this capacity.

Static member variables

C++ introduces two new uses for the static keyword when applied to classes: static member variables, and static member classes. 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 it’s 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_nValue -- one inside cFirst, and one inside cSecond. cFirst->m_nValue is different than cSecond->m_nValue.

Member variables of a class can be made static by using the static keyword. Static member variables only exist once in a program regardless of how many class objects are defined! One way to think about it is that all objects of a class share the static variables. Consider the following program:

This program produces the following output:


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

Although you can access static members through objects of the class type, this is somewhat misleading. cFirst.s_nValue implies that s_nValue belongs to cFirst, and this is really not the case. s_nValue does not belong to any object. In fact, s_nValue exists even if there are no objects of the class have been instantiated!

Consequently, it is better to think of static members as belonging to the class itself, not the objects of the class. Because s_nValue exists independently of any class objects, it can be accessed directly using the class name and the scope operator:

In the above snippet, s_nValue 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_nValue. This is the preferred method for accessing static members.

Initializing static member variables

Because static member variables are not part of the individual objects, you must explicitly define the static member if you want to initialize it to a non-zero value. The following line in the above example initializes the static member to 1:

This initializer should be placed in the code file for the class (eg. Something.cpp). In the absense of an initializing line, C++ will initialize the value to 0.

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_nIDGenerator is shared by all Something objects, when a new Something object is created, it’s constructor grabs the current value out of s_nIDGenerator and then increments the value for the next object. This guarantees that each 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 (eg. to look up the name of something, or to find a pre-calculated value). By making the lookup table static, only one copy exists for all objects, rather than 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

47 comments to 8.11 — Static member variables

  • 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”.

  • 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.

  • 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.

  • cammy

    In your first example how could GenerateID() evaluate to 0 if s_nID is set to 0 but then incremented before the end of the function? Should it not print the following

    • The function returns s_nID++; This means the value of s_nID is set aside, then s_nID is incremented, then the old value of s_nID is returned.

      For example, let’s say s_nID is 0. The value 0 is copied into a temp variable. s_nID is incremented to 1. Then the value 0 is returned.

      All of this happens transparently when you use the postfix ++ operator. That’s why using the prefix ++ operator can be more efficient.

  • Zelbacsi

    I’m so confused right now …

    In 4.2 you said not to use global variables:

    “2) To hold data that needs to be used by the entire program (eg. configuration settings).”
    (that’s what i’d need to do)

    “there are better ways to do #2 (eg. static classes).”
    Still, I didn’t found anything like “static classes” in later lessons. Did you mean this? (classes with static members) Although, from your examples, ‘static’ seems to serve an entirely different purpose in classes, then the one mentioned above in 2)

  • baldo

    Alex, I think you made a typo here: “C++ introduces two new uses for the static keyword when applied to classes: static member variables, and static member classes.” I think it is static member functions not classes.

  • heya

    small typo:
    In fact, s_nValue exists even if there are no objects of the class have been instantiated!
    should be
    In fact, s_nValue exists even if no objects of the class have been instantiated!

    or, you know, something similar. Nice website, I’ve learnt more here than in my university. They insist on “taking it slow” by teaching nothing more complex than pointers. You know, really incredibly abstract things like object oriented programming that only gurus and wise old men can know. I’m lucky they aren’t trying to ease me into c by teaching me pascal first (they did that up to this year).

  • srikanth

    i have a small question is static variable can be used in defining singleton of a class more efficently

  • 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


  • Dawid Chemloul

    -- edit deleted

  • 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.

  • abbas

    hey alex i have to questions
    Q1:what means about “hidden argument to the function” using this pointer.
    Q2: what means “function is called for an object”.

  • Ashish79

    Can we call non-static functions with static objects?

  • bobt

    “Because static member variables are not part of the individual objects, you must explicitly define the static member if you want to initialize it to a non-zero value.”

    It seems like this is incorrect. As many (including yourself) have pointed out if you comment out the definition then you will get a linker error. I suggest this wording instead:

    “Because static member variables are not part of the individual objects, you must always explicitly define the static member.”

  • ashly

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

  • 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.

  • Ashrin Tamim

    [int GenerateID()
    static int s_nID = 0;
    return s_nID++;

    int main()
    std::cout << GenerateID() << std::endl;
    std::cout << GenerateID() << std::endl;
    std::cout << GenerateID() << std::endl;
    return 0;

    Here the value of s_nID remains even after it goes out of scope.The value of s_nID does not destroy although each time calling the fungtion GenerateID zero is assigned to s_nID.Now


    using namespace std;

    class st
    static int s_nID;

    int GenerateID()
    static int s_nID = 0;
    return s_nID++;

    int change_value(int u)
    s_nID = u;
    return s_nID;

    int st :: s_nID = 1;
    int main()
    st g;
    std::cout << g.GenerateID() << std::endl;
    std::cout << g.GenerateID() << std::endl;
    std::cout << g.change_value(5) << std::endl;

    std::cout << g.GenerateID() << std::endl;
    return 0;
    If you run this program the result is:

    Instead of 2(the fourth line of output) there should be 6.

  • 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?

  • Harsh

  • puppi


    why we have to declare a static variable? int Something::s_nIDGenerator = 1; is it possible that we declare it in class? something like that a default variable

  • REM

    Fix the line in the text:
      "cFirst->m_nValue is different than cSecond->m_nValue."
    Should be:
      cFirst.m_nValue is different than cSecond.m_nValue

  • 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.

  • 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.

  • 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.

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

    This is an error:

  • 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.

  • ZNorQ


    First off; great site! I’ve tried figuring out C++ for a long time, and this is the site that managed to give me extensive and logical explanations to the C++ confusion. You’ve made C++ my primary choice!

    Anyway, in your text under the “Static member variables” heading you state the following;
    “C++ introduces two new uses for the static keyword when applied to classes: static member variables, and static member classes.”

    Shouldn’t it say “and static member functions” instead of “classes”?

    Kenneth aka ZNorQ.

Leave a Comment




six + 6 =

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