Is it good or okay practice to use a namespace as a static class? For example:
namespace MyStaticFunctions {
void doSomething();
}
Versus:
class MyStaticFunctions {
static void doSomething();
}
Namespace is a feature added in C++ and is not present in C. A namespace is a declarative region that provides a scope to the identifiers (names of functions, variables or other user-defined data types) inside it. Multiple namespace blocks with the same name are allowed.
Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.
Advantages of namespace In one program, namespace can help define different scopes to provide scope to different identifiers declared within them. By using namespace - the same variable names may be reused in a different program.
Classes are data types. They are an expanded concept of structures, they can contain data members, but they can also contain functions as members whereas a namespace is simply an abstract way of grouping items together. A namespace cannot be created as an object; think of it more as a naming convention.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With