6

Suppose you have the following non-static member function:

// .h
struct C {
    void f();
}

Now suppose you want to implement C::f by using some sub-functions specific to C::f, to make it shorter and more readable; for example:

// .cpp
void C::f() {
    h1();
    h2();
    //...
    hn();
}

suppose that many of those h()'s functions do not need to access any data members. This means that you may well define the functions either as static free functions (in one .cpp) or as member functions (static or not).

Would you make them static free functions or function members of C?

One advantage in the first case is that you will not have to declare them in C:

// .cpp
static void h1() {//...}
static void h2() {//...}
static void hn() {//...}

Also, if I am not wrong, there is no risk of global namespace pollution, since they are static, that is they can only be seen from other functions inside the same unit .cpp (in which C::f is also defined).

while in the second case you will have to declare them in C, although, as I said, they are only supposed to be used by C::f.

// .h
struct C {
    void f();
  private:
    static void h1(); // can be either static or non-static
    static void h2();
    static void hn();
}

// .cpp
void C::h1() {//...}
void C::h2() {//...}
void C::hn() {//...}

I think the second version results in bloated code for no good reason, above all if you end up having to split other long member functions like C::f to make the code more readable.

Martin
  • 9,089
  • 11
  • 52
  • 87
  • 2
    Instead of static free functions or member functions, I'd make them non-static, but inside an anonymous namespace. – Jerry Coffin Sep 04 '12 at 03:33
  • Why don't you just make a function object that encapsulates the helpers, or put the helpers in an anonymous namespace in the source file? – derpface Sep 04 '12 at 05:52

2 Answers2

4

I would suggest using an anonymous namespace:

namespace {
    void C::h1() {/...}
    void C::h2() {/...}
    void C::h3() {/...}
}

(see this question)

That way, you guarantee that the function is not visible outside the file it is defined and thus you are in no way polluting your global namespace - which would be my main concern for free static functions.

Making them private members of your class exposes the function interface to the whole world (as you publish your *.h file) and thus just makes the interface more complicated for no reason. (There are more arguments you could add here, for example higher compilation times when changing the definition of a private function)

Searching for "anonymous namespaces" results some interesting discussions on this topic.

Community
  • 1
  • 1
Thilo
  • 8,827
  • 2
  • 35
  • 56
  • 1
    but are you sure that free *static* functions hit the global namespace? Aren't static free functions local to the .cpp file in which they are defined only? – Martin Sep 04 '12 at 03:45
  • Yep, your right in that way. `static` caught me again. However, see http://stackoverflow.com/questions/4977252/why-unnamed-namespace-is-a-superior-alternative-to-static why it is still good to prefer anonymous namespaces. – Thilo Sep 04 '12 at 03:51
  • It is not that important anymore. The deprecation was removed for C++11, see [Deprecation of the static keyword - no more](http://stackoverflow.com/questions/4726570/deprecation-of-the-static-keyword-no-more) – Bo Persson Sep 04 '12 at 07:42
1

Only you can answer this question. If they will never be used outside of C::f then there is no point in polluting the global namespace. I personally would make them member functions of C. If they can be marked static, then do so, but if they really only matter to f, then just name them something that indicates that, and don't worry about the static.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • Ok, but there is not risk to pollute the global namespace in the first option I mentioned, because h()'s are *static* , that is local to the single .cpp file in which they would be grouped – Martin Sep 04 '12 at 03:40