Is it good or okay practice to use a namespace as a static class? For example:
namespace MyStaticFunctions {
void doSomething();
}
Vers
There's no such thing as a "static class" in C++, so from a C++ point of view you're not using it "as a static class", you're using it "as a namespace". It's certainly accepted practice to use namespaces to group functions together.
It's up to you, though, how big you want the groups to be. It's not unusual for C++ libraries to use a single namespace for the whole public interface. That might come as a surprise to someone who is used to (say) Java, where classes are often used to group together smaller numbers of static methods. Since C++ was here first, you could say that Java is using classes as namespaces.
So, in C++ you don't tend to see classes similar to java.util.Collections
or java.lang.Math
, full of static members. If you want groups of functions like that in C++, use namespaces.
The exception (isn't there always a special case in C++?) is traits types like std::numeric_limits<T>
, where the template parameter makes the class do something that a namespace can't do. You could define a namespace numeric_limits
containing function templates max<T>()
, min<T>()
etc, but it's not as good. Firstly, it groups things slightly differently, the type T
appears "lower down the hierarchy". Secondly it doesn't do everything that a traits type does, because there's no such thing as an "object template" that would let you define a value numeric_limits::digits<T>
.
I don't know C# well enough to comment on the practical uses of static classes there, but AFAIK it's just a class restricted to having no non-static members, so it's analogous to those Java classes.
In C++, you are actually encouraged at the language level to use a namespace
rather than a class
containing only static
methods because of Koenig's lookup (aka Argument Dependent Lookup).
Example:
namespace geometry {
struct Point { int x, y; };
double distance_from_center(Point const& p) {
return sqrt(p.x * p.x + p.y + p.y);
}
} // namespace geometry
int main() {
geometry::Point const p{3, 4}; // must qualify
std::cout << distance_from_center(p) << "\n"; // not qualified
}
If distance_from_center
is written as a static
method in a class
, then you need to explicitly qualify it each time.
It's a tough and interesting question for me personally, so decided to share my humble opinion
Considering the difference between "static" class (only static members) and namespace:
From maintenance point of view, sometimes you decide to make a class "static" (like a singleton), but then requirement changed and you need multiple instances. "Static" class would be easier to transform than namespace.
And, finally, to answer your question:
if you don't need special features of "static" class or namespace, use what you like more :)
It depends.
Is the method logically related to a class? If so, make it a member, otherwise place it in a namespace.
Functionally, they're the same, but there's more to code than function, right? For example, consider a method that returns the name of the class:
struct MyClass
{
static std::string getName() { return "MyClass"; }
}
You could obviously place the method outside, in a namespace
, and get the same result, but it logically belongs to the class.