44

Even though there are no static classes in C++, coming from a Java background I use to create a helper class like Util containing only static methods. Is this considered bad style or usual practice? One alternative I see is to use C functions (no class context at all). What other alternatives are there? What are there advantages and disadvantages and under which circumstances would I use any of these.

defining bunch of static methods in c++ suggests namespacing static functions as one alternative, though I fail to see what effects the static keyword without class context has.

Community
  • 1
  • 1
dcn
  • 4,389
  • 2
  • 30
  • 39
  • Read the answer of Charles Bailey in the post you linked to. static has a very different meaning in C++ when applied to free functions (functions without a class context) vs static class member functions – nos Sep 08 '11 at 09:48

8 Answers8

48

If you want to create a collection of utility functions without clobbering the global namespace, you should just create regular functions in their own namespace:

namespace utility {
    int helper1();
    void helper2();
};

You probably don't want to make them static functions either. Within the context of a non-member function (as opposed to a member function), the static keyword in C and C++ simply limits the scope of the function to the current source file (that is, it sort of makes the function private to the current file). It's usually only used to implement internal helper functions used by library code written in C, so that the resulting helper functions don't have symbols that are exposed to other programs. This is important for preventing clashes between names, since C doesn't have namespaces.

James O'Doherty
  • 2,186
  • 13
  • 14
  • 9
    For those transitioning from Java, be aware that the proper C++ standard terminology is "Within the context of a non-member function (as opposed to a member function)". This doesn't mean you have to follow that terminology, but some C++ programmers (including me) have a tiny little "what language are we talking about?" doubt every single time anyone talks about a "method" in C++. – Steve Jessop Sep 08 '11 at 10:08
  • 1
    @Steve, thanks for pointing that out! It's not as trivial as you make it sound. If you know what the standard terminology is for something, you can find better answers, especially if you have a book lying around and you're using the index to look up topics. That also means that for a lot of C++ discussions, the notion of a function is overloaded between what a lot of other languages would often call either a method or a function, so knowing that a "function" as it would be defined in another language is more specifically a "non-member function" in C++ seems quite significant to me. – James O'Doherty Sep 08 '11 at 12:16
18

In C++, classes with only static methods is mostly used in template metaprogramming.

For example, I want to calculate fibonacci numbers at compile-time itself, and at runtime I want them to print only, then I can write this program:

#include <iostream>

template<int N>
struct Fibonacci 
{
   static const int value = Fibonacci<N-1>::value + Fibonacci<N-2>::value;
   static void print()
   {
       Fibonacci<N-1>::print();
       std::cout << value << std::endl;
   }
};


template<>
struct Fibonacci<0>
{
   static const int value = 0;
   static void print()
   {
       std::cout << value << std::endl;
   }
};

template<>
struct Fibonacci<1>
{
   static const int value = 1;
   static void print()
   {
       Fibonacci<0>::print();
       std::cout << value << std::endl; 
   }
};

int main() {
        Fibonacci<20>::print(); //print first 20 finonacci numbers
        return 0;
}

Online demo : http://www.ideone.com/oH79u

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 3
    I am not sure *mostly* is really accurate, I think many programmers uses static classes to logically group a set of related functions (the (better?) alternative being free functions in a namespace). However, your answer is correct in that static member functions are widely used in TMP. – Luc Touraille Sep 08 '11 at 09:46
  • 5
    Noooo, not the Fibonacci example *again*! :) – Luc Touraille Sep 08 '11 at 09:47
  • @Luc: `I think many programmers uses static classes to logically group a set of related functions`. That is true, but such scenario are rather less than metaprogramming. – Nawaz Sep 08 '11 at 09:49
  • 2
    I'm afraid you might be overestimating the skills of C++ programmers over the world, but that might just be my pessimism talking :). – Luc Touraille Sep 08 '11 at 09:56
11

C++ is a multi paradigm language, so if you need some util functions that perhaps don't really fit in a class at all, then I would just make them free functions. I don't see a reason to put them into a class, just for OOP's sake.

There is no advantage that I can see to making all functions static and putting them in a class, over having them just as free functions. Personally, I think free functions are then an easier to work with option.

Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
  • 1
    You can then use namespaces if you want to group the functions together. – Andreas Vinter-Hviid Sep 08 '11 at 09:49
  • 2
    I know an advantage. If you want to make a group of functions friends of a class, it is easier and IMHO cleaner to put them in a class and friend the class instead of each individual function. Scenario I am thinking of would be factory methods needing access to private constructors, etc. – tokage Sep 08 '11 at 11:16
  • Another advantage is that you can also define private static helper functions, in case multiple utility functions have internal parts in common. – gentooise May 17 '19 at 14:50
7

As many others have pointed out, free functions inside a namespace is an approach that's often taken for this sort of thing in c++.

One case I'd make for classes with all static functions is when you'd like to expose a set of functions to information derived from template parameters, i.e.

template <typename Ty>
    class utils
{
public :
// if you need to setup a bunch of secondary types, based on "Ty" that will be used 
// by your utility functions
    struct item_type
    { 
        Ty data;
        // etc
    }; 

// a set of utilities
    static void foo(Ty &data1, item_type &item)
    { 
        // etc
    }
};

You can use this to achieve the effect of a template'd namespace:

int main ()
{
    double data;
    utils<double>::item_type item ;
    utils<double>::foo(data, item);

    return 0;
}

If you're not using templates just stick with namespaces.

Hope this helps.

Darren Engwirda
  • 6,915
  • 4
  • 26
  • 42
2

There is no real issue with declaring static methods within a class. Although namespaces are more suitable for this purpose for the reasons mentioned in the post you are referring to.

Using C functions can generate name collisions, unless you decide on a naming convention, prefixing your functions with stuff, for example btFunctionA, btFunctionB etc. You will want to keep your symbols within namespaces to avoid that, you are using C++ and not C after all.

Static functions within a namespace aren't any different from non-static. I believe the static keyword is simply ignored in this context.

EddieBytes
  • 1,333
  • 9
  • 20
2

In C++, just make them free functions. There's no need or reason to place them in a class at all. Unless you're doing shizzle with templates.

Puppy
  • 144,682
  • 38
  • 256
  • 465
1

There is one other situation in which a static class might be preferred to a namespace: when you want to make the data private so that it can't be directly modified from outside the class/namespace, but for performance reasons you want to have have public inline functions that operate on it. I don't think there is any way to do that with a namespace, other than by declaring a class inside the namespace.

dc42
  • 314
  • 3
  • 6
1

This may be relevant to your interests. It is an article that, uh, examines the different approaches to classes and functions in Java compared to other languages.

http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html

Matt
  • 3,778
  • 2
  • 28
  • 32