16

Possible Duplicates:
Where would you use a friend function vs a static function?
C++: static member functions

When is it appropriate to use a static member function in C++? Please give me a real world example.

Community
  • 1
  • 1
Umesha MS
  • 2,861
  • 8
  • 41
  • 60

7 Answers7

18

Good uses of static member functions:

  • Meta-programming. Real-world example is template std::char_traits. All member functions are static
  • Making it a static member function gives it access to private members of the class, although a friend would suffice here too
  • A protected static member function thus is accessible only to the class and classes derived from it.

Note that the last case applies to a protected static member function but not a private one. In the latter case you would just put it into the compilation unit of the class, hiding it away as an implementation detail. For a protected one though you want it to be visible, albeit in a restricted way.

A typical case of that one is "cheating" the lack of inheritance of friendship.

class B
{
   friend class A;
   // lots of private stuff
};

class A
{
protected:
   static void callsSomePrivateMembers( B& b );
};

class AChild : public A
{
   void foo( B& b );
}

void AChild::foo( B& b )
{
      // AChild does not have private access to B as friendship is not inherited
      // but I do have access to protected members of A including the static ones

    callsSomePrivateMembers( b ); // get to call them through a back-door
}
CashCow
  • 30,981
  • 5
  • 61
  • 92
  • +1 for the metaprogramming, but I don't get the "A member function that needs private access". Isn't this what regular member function do? – Simone Feb 07 '11 at 12:42
  • 1
    I meant that making it a static member function gives it access to private areas of the class. – CashCow Feb 07 '11 at 14:33
7

The natural place to use it is when you cannot use a free function because you need to access internals of the class. The most typical example of this is a builder function as below. The constructor of Foo is private to make sure that it is not constructed in any other way than with the builder function.

#include <iostream>

class Foo {
public:
  static Foo* createFoo() {return new Foo();}
private: 
  Foo() {}
};

int main() {
  //Foo nonBuiltFoo; //wont compile
  Foo* freshFoo = Foo::createFoo();
  delete freshFoo;
  return 0;
}

A typical use of that is earlier mentioned Singleton pattern. When you do not have to access protected and private parts of the class, static member functions is not necessary (free functions can be used), but there is some that uses static member functions also when it is within the domain of the class but not restricted/logical to use the function on a single instance.

daramarak
  • 6,115
  • 1
  • 31
  • 50
4

A common example you'll find (in a real world example) is when you are creating a thread. The common thread API's (POSIX/pthreads, Boost, and Win32 CreateThread) all require a specific signature. The only way to obtain that signature in a member function is by making the function static.

Zac Howland
  • 15,777
  • 1
  • 26
  • 42
3

You may want to use the function without an object instantiated. Also if the function is called from another static function it must be static.

Patryk
  • 1,421
  • 8
  • 21
  • Why is that (second point)? I'll admit I don't work in C++, so might be missing out on its intricacies, but at least in both C# and Java, static functions can use instance members just fine - all that's needed is to have an instance of the type. Is C++ different in this regard? – user Feb 07 '11 at 14:03
  • "You may want to use the function without an object instantiated" - it seems to be the only answer which actually answers the question! – TT_ stands with Russia Feb 05 '14 at 04:06
3

A typical example can be a singleton class where the static GetInstance() method returns the singleton instance of the class.

class Singleton
{
    static Singleton instance;

    private Singleton()
    {
    }

    static Singleton & GetInstance()
    {
      if(instance == null)
        instance = new Singleton();

      return instance;
    }
}
user
  • 6,897
  • 8
  • 43
  • 79
User234
  • 237
  • 1
  • 2
  • 9
  • 1
    It is better to use a function-level static instance of the class to accomplish the Singleton pattern. See "Meyers Singleton" (http://www.devarticles.com/c/a/Cplusplus/C-plus-plus-In-Theory-The-Singleton-Pattern-Part-I/4/) – Zac Howland Feb 07 '11 at 12:53
  • Would like to add...Using a singleton is advisable only after knowing the pros and cons it offers..Apart from few exceptional scenarios, Singletons usually end up creating more problems...Think..Threading issues..destruction of singleton... – Alok Save Feb 07 '11 at 15:08
2

I misread your question and answered when it's appropriate to use static functions.

You meant static member functions. here's an example of when to use a static member function - to wrap a thread call inside a class, so that your thread has access to your class...:

static unsigned WINAPI ArchiveAgent::LogMsgPump(PVOID pData)
{
    ArchiveAgent* pSmith = reinterpret_cast<ArchiveAgent*>(pData);

    if( pSmith )
        pSmith->LogMsgPump();
    else
        return -1;

    return 0;
}

unsigned WINAPI ArchiveAgent::LogMsgPump()
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);

    // ....

    CoUninitialize();
    return 0;
}

Here was my answer for plain old static functions.. I use static functions where it doesn't make sense for that function to belong to a class.

I generally tend to add these functions to a custom namespace. The following static function sample is part of a namespace I call ShellUtils:

static HRESULT CreateFolder( CString & sPath )
{
// create the destination folder if it doesn't already exist

HRESULT hr      = S_OK;
DWORD   dwError = 0;

if( sPath.GetLength() == 0 || sPath.GetLength() < 2 )                   
    return E_UNEXPECTED;

if( GetFileAttributes( (LPCWSTR) sPath ) == INVALID_FILE_ATTRIBUTES )
{           
    dwError = SHCreateDirectoryEx(NULL, (LPCWSTR)sPath, NULL);

    if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_EXISTS && dwError != ERROR_ALREADY_EXISTS)
        hr = HRESULT_FROM_WIN32(dwError);
}

return hr;

}

2

Please look up a design pattern called singleton.In short, It's one way to restrict creation of object. Thus the only way to create an object is to call a C++ member function which is static.

Ricko M
  • 1,784
  • 5
  • 24
  • 44