3

What are the (objective) disadvantages of creating a class where all members (attributes, functions) are static? In particular in comparison with the use of a namespace? Or would you rather create global variables/functions?

I like creating static attributes because I find them "tidier." (I know exactly where they come from, etc.) I'm not very familiar with namespaces. And I'm not comfortable at all with global variables, because I'm not very familiar with C keywords such as extern and static.

Further, if we consider the class

class MyStaticClass
{
    private:

        static int x;
        static double y;

    public:

        static float s;
        static double weatherForecast(unsigned int, char);
};

and the namespace

namespace MyNamespace
{
    int x;
    double y;
    float s;
    double weatherForecast(unsigned int, char);
}
  1. Are there differences (performance-wise) between calling MyStaticClass::weatherForecast and calling MyNamespace::weatherForecast?

  2. Are there differences (performance-wise) between reading/writing MyStaticClass::s and reading/writing MyNamespace::s?

  3. Would any of the answers to the above questions change if classes were used instead of primary types?

Pippin
  • 203
  • 1
  • 8
  • 3
    _"Or would you rather create a namespace?"_ I think that's the commonly agreed _best practice_ today. But that could just be an opinion. – πάντα ῥεῖ Jan 12 '16 at 13:21
  • 2
    why do you need them? A set of constants? + https://isocpp.org/wiki/faq/coding-standards#global-vars – Dmitry Ledentsov Jan 12 '16 at 13:22
  • https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables, this could be usefull. – 88877 Jan 12 '16 at 13:25
  • 4
    @88877 - The Google style guide is specific to the long history of Google's code base, and is not very useful when writing new code. – Bo Persson Jan 12 '16 at 13:27
  • This question is primarily opinion based. It also depends on individual's coding style and the guidelines followed by him/her based on his current work. There can be many answers for this question. I personally feel this does not fall under the stackoverflow valid questions as mentioned at http://stackoverflow.com/help/on-topic – phoenix Jan 12 '16 at 13:31
  • @Sri.U: Agree, I've rephrased the question to avoid that. – MSalters Jan 12 '16 at 13:31
  • Yes I would need a set of constants. Basically my project has a few sets of constants, each with the appropriate set of functions, and I chose to get these sets together in classes. Is it really unwise to create a "purely static" class (a class that will never be constructed) rather than a namespace? – Pippin Jan 12 '16 at 13:31
  • Sorry for the bad question, and thanks for correcting it @MSalters – Pippin Jan 12 '16 at 13:36

1 Answers1

9

Is it "good practice" to create a class where all members (attributes, functions) are static?

This is called "monostate" and it depends.

Or would you rather create a namespace?

A class with static functions can be a template argument, whereas a namespace cannot. On the other hand, namespaces allow for argument-dependent lookup, whereas classes - less so.

Or would you rather create global variables/functions?

Some things are truly global, like the standard streams, Logger objects, event loop engines (thread-specific global). For example, code that passes Logger objects in each and every call or stores them as member variables is more complicated than necessary, IMO.

There is an often cited misconception that the order of dynamic initialization accross translation units is undefined, so people overuse Singletons instead of plain globals to make sure the Singleton object is initialized before its first use. However, there is a portable technique called Schwarz Counter that is used for initializing the standard streams (std::cout and friends), which makes sure that these globals are initialized before their first use even before main is entered.


Answers to your updated questions: no, no, no.

Maxim Egorushkin
  • 119,842
  • 14
  • 147
  • 239
  • 1
    Especially pleased with the debunking of syngleton. – SergeyA Jan 12 '16 at 15:03
  • Hello, thank you for your answer. I have updated the original post and listed more precise questions. @MSalters – Pippin Jan 13 '16 at 13:57
  • I read recently that actually, the Schwarz Counter is a frowned-upon technique in some cases. For instance, in the LLVM project coding standards http://llvm.org/docs/CodingStandards.html they write "The use of #include in library files is hereby forbidden, because many common implementations transparently inject a static constructor into every translation unit that includes it." The issue is that all this static init causes measurable and unnecessary program startup cost, for every program that links to llvm. – Chris Beck Jan 13 '16 at 16:39
  • @ChrisBeck Some projects go to extreme lengths to avoid using the standard C and C++ libraries to speed-up start-up. Are these libraries also thrown upon? I would say benchmark and make a judgement. Singletons have run-time costs (checking the instance pointer), whereas Schwarz Counter only has a cost at start-up. – Maxim Egorushkin Jan 13 '16 at 17:58
  • @ChrisBeck I wonder which C++ library does not use Schwarz Counter to initialize `std::cout` and friends? – Maxim Egorushkin Jan 13 '16 at 17:59
  • @Maxim Yeah, that's a good point (about the run-time vs start-up time). I also don't know which C++ library they seem to refer to that doesn't use this technique for `iostream`. – Chris Beck Jan 13 '16 at 18:00
  • 2
    @MaximEgorushkin Initialization order of static objects across compilation units is, in fact, not well-defined. This is even stated in the motivation for the Schwartz Counter you link to. Being wary of plain globals, if they have non-trivial initialization, is justified. – Danra Jan 13 '17 at 16:56