312

How do you create a static class in C++? I should be able to do something like:

cout << "bit 5 is " << BitParser::getBitAt(buffer, 5) << endl;

Assuming I created the BitParser class. What would the BitParser class definition look like?

Onur A.
  • 3,007
  • 3
  • 22
  • 37
andrewrk
  • 30,272
  • 27
  • 92
  • 113
  • 9
    @Vagrant a function inside a namespace is still a function. A function that belongs to a class is called a method. If it is a static method, you invoke it similarly as if it was a function inside a namespace. –  Sep 27 '12 at 16:42
  • @superjoe30 As far as I know, there is one good use for a "static" class: specialization of an overloaded template function - see "Moral #2" [here](http://www.gotw.ca/publications/mill17.htm). – bcrist Dec 30 '13 at 01:01
  • 3
    IMO container-like classes (having just static methods) are useful in certain cases. – AarCee May 17 '18 at 11:16
  • Static class templates can be used to remove redundant type declarations across multiple class templates. – anni Dec 20 '19 at 19:07

15 Answers15

329

If you're looking for a way of applying the "static" keyword to a class, like you can in C# for example, then you won't be able to without using Managed C++.

But the looks of your sample, you just need to create a public static method on your BitParser object. Like so:

BitParser.h

class BitParser
{
 public:
  static bool getBitAt(int buffer, int bitIndex);

  // ...lots of great stuff

 private:
  // Disallow creating an instance of this object
  BitParser() {}
};

BitParser.cpp

bool BitParser::getBitAt(int buffer, int bitIndex)
{
  bool isBitSet = false;
  // .. determine if bit is set
  return isBitSet;
}

You can use this code to call the method in the same way as your example code.

Zoe
  • 27,060
  • 21
  • 118
  • 148
OJ.
  • 28,944
  • 5
  • 56
  • 71
  • 110
    To make your intention clear in this approach you can additionally use a private constructor. `private: BitParser() {}` This will prevent anyone from creating instances. – Danvil Jul 22 '10 at 15:38
  • 5
    OJ, you have [a syntax error](http://cplusplus.syntaxerrors.info/index.php?title=Cannot_declare_member_function_%E2%80%98static_int_Foo::bar()%E2%80%99_to_have_static_linkage). The static keyword should only be used in the class definition, and not in the method definition. – andrewrk Aug 13 '08 at 18:02
  • 8
    @MoatazElmasry thread safety is a problem when you share state. In the above implementation there is no state shared, so there can not be any issues with thread safety ... unless you're stupid enough to use statics _inside_ those functions. So yes, the code above is thread safe, just keep persistent state out of your functions and you're good. – OJ. Aug 25 '12 at 21:25
  • @MoatazElmasry Incorrect. Two threads can't modify non-static local variables in a static function. – OJ. Aug 27 '12 at 02:02
  • 1
    If your attempt is to have the similar behavior of the _C# static classes_, you should mark the class as sealed with the `final` keyword (from C++11) to prevent any other class to inherit from. – Jämes May 27 '17 at 20:57
  • 38
    If C++11, I'd argue it's better to `BitParser() = delete;` to properly convey the intention of removing the constructor (not just hiding it as `private`). – phoenix Jul 06 '18 at 13:25
285

Consider Matt Price's solution.

  1. In C++, a "static class" has no meaning. The nearest thing is a class with only static methods and members.
  2. Using static methods will only limit you.

What you want is, expressed in C++ semantics, to put your function (for it is a function) in a namespace.

Edit 2011-11-11

There is no "static class" in C++. The nearest concept would be a class with only static methods. For example:

// header
class MyClass
{
   public :
      static void myMethod() ;
} ;

// source
void MyClass::myMethod()
{
   // etc.
}

But you must remember that "static classes" are hacks in the Java-like kind of languages (e.g. C#) that are unable to have non-member functions, so they have instead to move them inside classes as static methods.

In C++, what you really want is a non-member function that you'll declare in a namespace:

// header
namespace MyNamespace
{
   void myMethod() ;
}

// source
namespace MyNamespace
{
   void myMethod()
   {
      // etc.
   }
}

Why is that?

In C++, the namespace is more powerful than classes for the "Java static method" pattern, because:

  • static methods have access to the classes private symbols
  • private static methods are still visible (if inaccessible) to everyone, which breaches somewhat the encapsulation
  • static methods cannot be forward-declared
  • static methods cannot be overloaded by the class user without modifying the library header
  • there is nothing that can be done by a static method that can't be done better than a (possibly friend) non-member function in the same namespace
  • namespaces have their own semantics (they can be combined, they can be anonymous, etc.)
  • etc.

Conclusion: Do not copy/paste that Java/C#'s pattern in C++. In Java/C#, the pattern is mandatory. But in C++, it is bad style.

Edit 2010-06-10

There was an argument in favor to the static method because sometimes, one needs to use a static private data member.

I disagree somewhat, as show below:

The "Static private member" solution

// HPP

class Foo
{
   public :
      void barA() ;
   private :
      void barB() ;
      static std::string myGlobal ;
} ;

First, myGlobal is called myGlobal because it is still a global private variable. A look at the CPP source will clarify that:

// CPP
std::string Foo::myGlobal ; // You MUST declare it in a CPP

void Foo::barA()
{
   // I can access Foo::myGlobal
}

void Foo::barB()
{
   // I can access Foo::myGlobal, too
}

void barC()
{
   // I CAN'T access Foo::myGlobal !!!
}

At first sight, the fact the free function barC can't access Foo::myGlobal seems a good thing from an encapsulation viewpoint... It's cool because someone looking at the HPP won't be able (unless resorting to sabotage) to access Foo::myGlobal.

But if you look at it closely, you'll find that it is a colossal mistake: Not only your private variable must still be declared in the HPP (and so, visible to all the world, despite being private), but you must declare in the same HPP all (as in ALL) functions that will be authorized to access it !!!

So using a private static member is like walking outside in the nude with the list of your lovers tattooed on your skin : No one is authorized to touch, but everyone is able to peek at. And the bonus: Everyone can have the names of those authorized to play with your privies.

private indeed... :-D

The "Anonymous namespaces" solution

Anonymous namespaces will have the advantage of making things private really private.

First, the HPP header

// HPP

namespace Foo
{
   void barA() ;
}

Just to be sure you remarked: There is no useless declaration of barB nor myGlobal. Which means that no one reading the header knows what's hidden behind barA.

Then, the CPP:

// CPP
namespace Foo
{
   namespace
   {
      std::string myGlobal ;

      void Foo::barB()
      {
         // I can access Foo::myGlobal
      }
   }

   void barA()
   {
      // I can access myGlobal, too
   }
}

void barC()
{
   // I STILL CAN'T access myGlobal !!!
}

As you can see, like the so-called "static class" declaration, fooA and fooB are still able to access myGlobal. But no one else can. And no one else outside this CPP knows fooB and myGlobal even exist!

Unlike the "static class" walking on the nude with her address book tattooed on her skin the "anonymous" namespace is fully clothed, which seems quite better encapsulated AFAIK.

Does it really matter?

Unless the users of your code are saboteurs (I'll let you, as an exercise, find how one can access to the private part of a public class using a dirty behaviour-undefined hack...), what's private is private, even if it is visible in the private section of a class declared in a header.

Still, if you need to add another "private function" with access to the private member, you still must declare it to all the world by modifying the header, which is a paradox as far as I am concerned: If I change the implementation of my code (the CPP part), then the interface (the HPP part) should NOT change. Quoting Leonidas : "This is ENCAPSULATION!"

Edit 2014-09-20

When are classes static methods are actually better than namespaces with non-member functions?

When you need to group together functions and feed that group to a template:

namespace alpha
{
   void foo() ;
   void bar() ;
}

struct Beta
{
   static void foo() ;
   static void bar() ;
};

template <typename T>
struct Gamma
{
   void foobar()
   {
      T::foo() ;
      T::bar() ;
   }
};

Gamma<alpha> ga ; // compilation error
Gamma<Beta> gb ;  // ok
gb.foobar() ;     // ok !!!

Because, if a class can be a template parameter, a namespaces cannot.

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
paercebal
  • 81,378
  • 38
  • 130
  • 159
  • 4
    GCC supports -fno-access-control, which can be used in whitebox unit tests to access otherwise private class members. That's about the only reason I can think of to justify using a class member instead of an anonymous/static global in the implementation. – Tom Sep 10 '10 at 13:59
  • 8
    @Tom: A cross-platform solution would be to add the following code `#define private public` in the headers... ^_^ ... – paercebal Sep 10 '10 at 17:20
  • 1
    @Tom: anyway, IMHO, even considering unit testing, the cons of "showing too much stuff" outweights the pros. I guess an alternative solution would be to put the code to be tested in a function taking the needed parameters (and no more) in a `utilities` namespace. This way, this function can be unit-tested, and still have no special access to private members (as they are given as parameters at the function call)... – paercebal Sep 10 '10 at 17:26
  • @paercebal I'm about to jump onboard your ship, but I have one final reservation. If someone jumps in your `namespace` will they not gain access to your `global`, albeit hidden, members? Obviously they would have to guess, but unless you are intentionally obfuscating your code, variable names are pretty easy to guess. – Zak Sep 19 '14 at 20:32
  • @Zak : Indeed, they could, but only by trying to do it in the CPP file where the myGlobal variable is declared. The point is more visibility than accessibility. In the static class, the myGlobal variable is private, but still visible. This is not as important as it seems, but still, in a DLL, showing a symbol that should be private to the DLL in an exported header could be awkward... In the namespace, the myGlobal exists only in the CPP file (you can even go farther and make it static). That variable doesn't appear in the public headers. – paercebal Sep 20 '14 at 22:09
  • @paercebal So by putting them in the anonymous `namespace` you are sealing the variables? In your answer can you break from your analogy and explain the mechanism of the `namespace` in greater technical detail (as in constraints imposed)? – Zak Sep 23 '14 at 00:39
  • [unnamed namespaces vs. static variables/functions](http://stackoverflow.com/questions/154469/unnamed-anonymous-namespaces-vs-static-functions) – Zak Sep 25 '14 at 16:51
  • @paercebal, and also `#define class struct` to catch members that default to private at the beginning of the class. But that seems like it might break some things? Do you see any way it could? – Tyler Feb 24 '16 at 19:12
  • "But you must remember that "static classes" are hacks .. in languages like C#." - That is just wrong, it's not a hack, it's an expression of intent, one that C++ simply lacks. You've made the mistake of thinking that static functions are always just a loose collection of related/unrelated functions. That's not true at all. A static class follows the class model, but it has the extra restrictions that it can't be instantiated, it's a single / static class, available where you need it. Typically I would make CoreGraphics a static class for example, because it is used across the namespace. – Gavin Williams Sep 17 '21 at 05:26
  • The lack of memberless functions in C# is a separate issue to static classes. It's a missing feature in C# for sure and you can use static classes to mimic that intent (because it looks exactly the same). But thinking that static classes is just a hack to provide memberless functions is wrong. – Gavin Williams Sep 17 '21 at 05:33
71

You can also create a free function in a namespace:

In BitParser.h

namespace BitParser
{
    bool getBitAt(int buffer, int bitIndex);
}

In BitParser.cpp

namespace BitParser
{
    bool getBitAt(int buffer, int bitIndex)
    {
        //get the bit :)
    }
}

In general this would be the preferred way to write the code. When there's no need for an object don't use a class.

Matt Price
  • 43,887
  • 9
  • 38
  • 44
  • 2
    In some cases you may want to have data encapsulation even if the class is mostly "static". Static private class members will give you this. Namespace members are always public and cannot provide data encapsulation. – Torleif May 12 '09 at 19:34
  • If the "member" var is only declared and accessed from the .cpp file, it is more private than a private var declared in the .h file. NOT that I recommend this technique. – jmucchiello Apr 26 '10 at 19:03
  • 4
    @Torleif : You're wrong. namespaces are better for encapsulation than static private members. See my answer for demonstration. – paercebal Jun 10 '10 at 22:14
  • 1
    yes but in namespace you have to keep the function order, in contrast to class with static members, for example void a(){b();} b(){} would yield an error in a namespace but not in a class with static members – Moataz Elmasry Aug 23 '12 at 13:08
13

If you're looking for a way of applying the "static" keyword to a class, like you can in C# for example

static classes are just the compiler hand-holding you and stopping you from writing any instance methods/variables.

If you just write a normal class without any instance methods/variables, it's the same thing, and this is what you'd do in C++

Orion Edwards
  • 121,657
  • 64
  • 239
  • 328
  • Not to complain (especially at you), but some compiler hand-holding to keep me from writing or cut/pasting the word `static` 200 times would be a good thing. – 3Dave Nov 06 '13 at 01:07
  • Agreed - but a static class in C# doesn't do this either. It just fails to compile when you forget to paste static in there :-) – Orion Edwards Nov 10 '13 at 21:29
  • Yeah - fair enough. My macros are showing. Honestly, if I declare the class as static, the compiler should only throw an error if I try to instantiate it. Rules that require me to repeat myself are obnoxious and should be the first against the wall when the revolution comes. – 3Dave Nov 10 '13 at 22:02
12

Can I write something like static class?

No, according to the C++11 N3337 standard draft Annex C 7.1.1:

Change: In C ++, the static or extern specifiers can only be applied to names of objects or functions. Using these specifiers with type declarations is illegal in C ++. In C, these specifiers are ignored when used on type declarations. Example:

static struct S {    // valid C, invalid in C++
  int i;
};

Rationale: Storage class specifiers don’t have any meaning when associated with a type. In C ++, class members can be declared with the static storage class specifier. Allowing storage class specifiers on type declarations could render the code confusing for users.

And like struct, class is also a type declaration.

The same can be deduced by walking the syntax tree in Annex A.

It is interesting to note that static struct was legal in C, but had no effect: Why and when to use static structures in C programming?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
11

In C++ you want to create a static function of a class (not a static class).

class BitParser {
public:
  ...
  static ... getBitAt(...) {
  }
};

You should then be able to call the function using BitParser::getBitAt() without instantiating an object which I presume is the desired result.

Philip Reynolds
  • 9,364
  • 3
  • 30
  • 37
10

As it has been noted here, a better way of achieving this in C++ might be using namespaces. But since no one has mentioned the final keyword here, I'm posting what a direct equivalent of static class from C# would look like in C++11 or later:

class BitParser final
{
public:
  BitParser() = delete;

  static bool GetBitAt(int buffer, int pos);
};

bool BitParser::GetBitAt(int buffer, int pos)
{
  // your code
}
Mikhail Vasilyev
  • 503
  • 4
  • 11
5

You 'can' have a static class in C++, as mentioned before, a static class is one that does not have any objects of it instantiated it. In C++, this can be obtained by declaring the constructor/destructor as private. End result is the same.

Netzer
  • 51
  • 1
  • 1
  • What you are suggesting might create a singleton Class, but it is not the same as a static class. – ksinkar Oct 17 '17 at 11:40
4

Unlike other managed programming language, "static class" has NO meaning in C++. You can make use of static member function.

4

In Managed C++, static class syntax is:-

public ref class BitParser abstract sealed
{
    public:
        static bool GetBitAt(...)
        {
            ...
        }
}

... better late than never...

Malc B
  • 91
  • 3
3

This is similar to C#'s way of doing it in C++

In C# file.cs you can have private var inside a public function. When in another file you can use it by calling the namespace with the function as in:

MyNamespace.Function(blah);

Here's how to imp the same in C++:

SharedModule.h

class TheDataToBeHidden
{
  public:
    static int _var1;
    static int _var2;
};

namespace SharedData
{
  void SetError(const char *Message, const char *Title);
  void DisplayError(void);
}

SharedModule.cpp

//Init the data (Link error if not done)
int TheDataToBeHidden::_var1 = 0;
int TheDataToBeHidden::_var2 = 0;


//Implement the namespace
namespace SharedData
{
  void SetError(const char *Message, const char *Title)
  {
    //blah using TheDataToBeHidden::_var1, etc
  }

  void DisplayError(void)
  {
    //blah
  }
}

OtherFile.h

#include "SharedModule.h"

OtherFile.cpp

//Call the functions using the hidden variables
SharedData::SetError("Hello", "World");
SharedData::DisplayError();
sth
  • 222,467
  • 53
  • 283
  • 367
John
  • 31
  • 1
2

One (of the many) alternative, but the most (in my opinion) elegant (in comparison to using namespaces and private constructors to emulate the static behavior), way to achieve the "class that cannot be instantiated" behavior in C++ would be to declare a dummy pure virtual function with the private access modifier.

class Foo {
   public:
     static int someMethod(int someArg);

   private:
     virtual void __dummy() = 0;
};

If you are using C++11, you could go the extra mile to ensure that the class is not inherited (to purely emulate the behavior of a static class) by using the final specifier in the class declaration to restrict the other classes from inheriting it.

// C++11 ONLY
class Foo final {
   public:
     static int someMethod(int someArg);

   private:
      virtual void __dummy() = 0;
};

As silly and illogical as it may sound, C++11 allows the declaration of a "pure virtual function that cannot be overridden", which you can use alongside declaring the class final to purely and fully implement the static behavior as this results in the resultant class to not be inheritable and the dummy function to not be overridden in any way.

// C++11 ONLY
class Foo final {
   public:
     static int someMethod(int someArg);

   private:
     // Other private declarations

     virtual void __dummy() = 0 final;
}; // Foo now exhibits all the properties of a static class
hecate
  • 620
  • 1
  • 8
  • 33
1
class A final {
  ~A() = delete;
  static bool your_func();
}

final means that a class cannot be inherited from.

delete for a destructor means that you can not create an instance of such a class.

This pattern is also know as an "util" class.

As many say the concept of static class doesn't exist in C++.

A canonical namespace that contains static functions preferred as a solution in this case.

1

There is no such thing as a static class in C++. The closest approximation is a class that only contains static data members and static methods. Static data members in a class are shared by all the class objects as there is only one copy of them in memory, regardless of the number of objects of the class. A static method of a class can access all other static members ,static methods and methods outside the class

0

One case where namespaces may not be so useful for achieving "static classes" is when using these classes to achieve composition over inheritance. Namespaces cannot be friends of classes and so cannot access private members of a class.

class Class {
 public:
  void foo() { Static::bar(*this); }    

 private:
  int member{0};
  friend class Static;
};    

class Static {
 public:
  template <typename T>
  static void bar(T& t) {
    t.member = 1;
  }
};
Josh Olson
  • 397
  • 2
  • 15