Navigation



8.12 — Static member functions

In the previous lesson on static member variables, you learned that classes can have member variables that are shared across all objects of that class type. However, what if our static member variables are private? Consider the following example:

class Something
{
private:
    static int s_nValue;

};

int Something::s_nValue = 1; // initializer

int main()
{
    // how do we access Something::s_nValue?
}

In this case, we can’t access Something::s_nValue directly from main(), because it is private. Normally we access private members through public member functions. While we could create a normal public member function to access s_nValue, we’d then need to instantiate an object of the class type to use the function! We can do better. In this case, the answer to the problem is that we can also make member functions static.

Like static member variables, static member functions are not attached to any particular object. Here is the above example with a static member function accessor:

class Something
{
private:
    static int s_nValue;
public:
    static int GetValue() { return s_nValue; }
};

int Something::s_nValue = 1; // initializer

int main()
{
    std::cout << Something::GetValue() << std::endl;
}

Because static member functions are not attached to a particular object, they can be called directly by using the class name and the scope operator. Like static member variables, they can also be called through objects of the class type, though this is not recommended.

Static member functions have two interesting quirks worth noting. First, because static member functions are not attached to an object, they have no this pointer! This makes sense when you think about it — the this pointer always points to the object that the member function is working on. Static member functions do not work on an object, so the this pointer is not needed.

Second, static member functions can only access static member variables. They can not access non-static member variables. This is because non-static member variables must belong to a class object, and static member functions have no class object to work with!

Here’s another example using static member variables and functions:

class IDGenerator
{
private:
    static int s_nNextID;

public:
     static int GetNextID() { return s_nNextID++; }
};

// We'll start generating IDs at 1
int IDGenerator::s_nNextID = 1;

int main()
{
    for (int i=0; i < 5; i++)
        cout << "The next ID is: " << IDGenerator::GetNextID() << endl;

    return 0;
}

This program prints:

The next ID is: 1
The next ID is: 2
The next ID is: 3
The next ID is: 4
The next ID is: 5

Note that because all the data and functions in this class are static, we don’t need to instantiate an object of the class to make use of it’s functionality! This class utilizes a static member variable to hold the value of the next ID to be assigned, and provides a static member function to return that ID and increment it.

Be careful when writing classes with all static members like this. Although such “pure static classes” can be useful, they also come with some potential downsides. First, because all of the members belong to the class, and the class is accessible from anywhere in the program, it’s essentially the equivalent of declaring a global variable of the class type. In the section on global variables, you learned that global variables are dangerous because one piece of code can change the value of the global variable and end up breaking another piece of seemingly unrelated code. The same holds true for pure static classes. Second, because all static members are instantiated only once, there is no way to have multiple copies of a pure static class (without cloning the class and renaming it). For example, if you needed two independent IDGenerators, this would not be possible.

8.13 — Friend functions and classes
Index
8.11 — Static member variables

25 comments to 8.12 — Static member functions

  • tony

    Very good explanation and examples..

  • [...] 2007 Prev/Next Posts « 8.10 — Const class objects and member functions | Home | 8.12 — Static member functions » Friday, September 14th, 2007 at 9:50 [...]

  • [...] 2007 Prev/Next Posts « 8.12 — Static member functions | Home | 9.1 — Introduction to operator overloading » Thursday, September 20th, [...]

  • heya

    we don’t need to instantiate an object of the class to make use of it’s functionality!

    it’s should be its

    heh, this reminds me of editing wikipedia. Always correcting small errors no one notices but never adding anything useful.

  • San

    The examples are simply simple to understand the concept…Thanks a lot

  • anon

    Absolutely short and sweet !

  • peter

    Hi Alex,

    Did not understand the following….Can u explain?

    “Second, because all static members are instantiated only once, there is no way to have multiple copies of a pure static class (without cloning the class and renaming it). For example, if you needed two independent IDGenerators, this would not be possible.”

    What do u mean by two IDgenerators? Is it two classes?
    Can some one explain the above paragraph in detail

    • 4lgor1thm

      Hi, Peter

      “Second, because all static members are instantiated only once, there is no way to have multiple copies of a pure static class (without cloning the class and renaming it).”

      Static Classes can only have one instance derived from them (not an object, but a call to the static class itself.). Non-static classes can have an infinite number of instance derived from them (objects). Consider the example below; it’s an excerpt from a small Console app I wrote in Visual C++ Studio Express 2010:

      ———————————————————————————————-
      // StaticClasses.cpp : main project file.

      #include “stdafx.h”

      using namespace System;

      //Our pure static class can only contain static items …
      static class StaticClass
      {
      private:
      static int s_nValue;

      public:
      static int getValue(){return s_nValue++;}
      };

      class DynamicClass
      {
      private:
      int m_nValue;

      public:
      DynamicClass(){m_nValue = 1;}
      int getValue(){return m_nValue++;}
      };

      int StaticClass::s_nValue = 0;

      int main(array ^args)
      {
      StaticClass cStaticClass;

      //cStaticClass::getValue(); //Throws an exception, cannot access static methods and variables of an instantiated object of a static class

      //in the tutorial the author said it can be instantiated once
      //This is the reason why it holds on to its value even out of class scope.
      //Here we have one copy, the static class
      Console::WriteLine(L”StaticClass getValue call: ” + StaticClass::getValue());
      Console::WriteLine(L”StaticClass getValue call: ” + StaticClass::getValue());

      //in order to have multiple copies of the class, we need to create a non-static class, and instantiate at least 2 objects
      DynamicClass cClass1;
      DynamicClass cClass2;

      //here 2 objects are being instantiated from a non-static class; here we have 2 copies, the same way we could use 2 different IDGenerators.
      Console::WriteLine(L”Instantiated Object 1: ” + cClass1.getValue());
      Console::WriteLine(L”Instantiated Object 2: ” + cClass2.getValue());

      Console::WriteLine(L”Press any key to continue …”);
      Console::ReadLine();
      return 0;
      }

      ———————————————————————————————-

      “… if you needed two independent IDGenerators, this would not be possible.”

      You can only derive one instance from a static class, and it is not an object.

      I Hope this helps …

      4lgor1thm

      • peter

        Thanks 4lgor1thm…:)

      • uma

        //cStaticClass::getValue(); //Throws an exception, cannot access static methods and variables of an instantiated object of a static class

        this error i am not getting
        cStaticClass.getvalue();—-> i have written iike this i am not getting any error
        cStaticClass is a object right so we can access member function or data of the claa by dot operator right.

        y can u explain me in detail why i am not getting error

      • Seems STATIC classes are not supported under C++ … ??

        When I tried to compile the above code I get error saying
        “error: a storage class can only be specified for objects and functions”

  • SUN

    Hello Alex,

    Can you please explain me what is the use of making a constructor static and when we need to do that ?

    • leon.li

      hi, SUN, I think static constructor is used for :
      1.initiating some static member variables of a class;
      2.if you don’t write the static constructor, and your class has some static member variables which already given the initial values, the compiler will automated generate a static constructor for you.
      3. I think in database singleton design mode, it is useful. Because we don’t want to generate too much accessing thread for the database, it is waste the resource.

      thanks.

  • The whole of this example, with all of the static variables and methods, produces dangerous code. Threading becomes difficult (you have to build your own locks) and anybody can get to the variables from anywhere without the richness of the various c++ tools like boost, etc. This is completely done without problems, allowing the richness of the various other libraries that are aimed at OS management with a Singleton Pattern. I like the example (a href=”http://www.yolinux.com/TUTORIALS/C++Singleton.html” title=”here.”>

  • ankit shukla

    friend function in c++ is that in which the two classes directly communicate each other.but it breaks the priciple of data hiding, is it

  • deajosha

    thanks a lot for sharing.

  • Debdipta

    What is difference in ‘Static’ in C and C++?

  • tunvir rahman tusher

    Static is an alternative name of global variable.When you define a variable static its only one copy will be created and all object must share the same copy of the variable.
    try this one

    #include
    using namespace std;
    class static_try
    {
    public:
    static_try(int c){b=c;}
    static int a;////static variable(one copy will be created!)
    int b;

    };
    int static_try::a=1;/////must be initialized outside class
    int main()
    {
    static_try s(2);
    // s.out();
    cout<<s.a<<" "<<s.b<<endl;////s share a
    static_try s1(3);
    cout<<s1.a<<" "<<s1.b;///s1 also share a
    getchar();

    }
    hope you have got it.Thanks

  • mohsenkazemi

    hi everyone,
    i have a question here, i want to define a member function a static function because i want to create a thread on it, but as you said a static member function only have access to static variable, when i was working with MFC flexgrix forms i cant’t define those variable(variables how handle the grid forms) as a static variable, please guide me to resolve that,
    best regards

  • stheurkar

    class IDGenerator
    {
    private:
    static int s_nNextID;

    public:
    static int GetNextID() { return s_nNextID++; }
    };

    // We’ll start generating IDs at 1
    int IDGenerator::s_nNextID = 1;

    How is it possible to access s_NextID defined under private access specifier in the line above.

  • calicratis19

    Hi I love your tutorial very much. Its like having a discussion with friend. It helped me a lot :) Thanks for that. Today I tried to read about static keyword in here. It was really confusing to me when it comes to the linkage. I get really confused about the linkage of static and inline functions. Can you please write a tutorial about that too? I think its a really important topic missed by learncpp. It will be really helpful also. Thanks again for your tremendous effort with this blog. A lot of us are very grateful :)

You must be logged in to post a comment.