Using a namespace in place of a static class in C++?

前端 未结 4 1775
一整个雨季
一整个雨季 2020-12-29 03:29

Is it good or okay practice to use a namespace as a static class? For example:

namespace MyStaticFunctions {
    void doSomething();
}

Vers

相关标签:
4条回答
  • 2020-12-29 03:44

    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.

    0 讨论(0)
  • 2020-12-29 03:47

    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.

    0 讨论(0)
  • 2020-12-29 04:05

    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:

    1. a namespace can be scattered over multiple files: additional flexibility but should be used carefully.
    2. a namespace provides argument dependent lookup (see Matthieu M. answer): useful in specific situations
    3. a "static" class can have access modifiers and can form an hierarchy: I think private members declared in class interface and visible to its clients is a C++ feature that was dictated more by technical, not logical reasons. I don't see any benefits of private static members. Protected members for "static" hierarchy? Never seen any.
    4. a "static" class can be a "template", in addition to template members: see Steve Jessop's answer for a great example from STL

    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 :)

    0 讨论(0)
  • 2020-12-29 04:07

    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.

    0 讨论(0)
提交回复
热议问题