Consider Matt Price's solution.
- In C++, a "static class" has no meaning. The nearest thing is a class with only static methods and members.
- 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 member variable.
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.