One factor is whether to even put them in a class, or just put them as nomembers in a namespace (in Java, you'd have to use a class, but C++ offers namespaces).
If you do make it a class member, then the most important decision you have to make about each function is whether it would require or should affect any state that is not received or passed via a its parameters and return value. If it does not, then it should be made static
, since you will not use the "this" hidden argument.
One argument for using a class instead of a namespace is if your utility class may need to invoke additional methods for its implementation (e.g., in a case of recursion, complex calculations, etc.). You could then make your method static public
, and anything it is implemented over static private
. It's been many years since I used C++, but I don't think you can "hide" non-member functions in a namespace (someone correct me if I'm wrong).
In terms of designing the function interface, consider the number of arguments. If there are too many incoming arguments (especially if they are of similar types and some are related), you may want to consider using additional types instead of passing multiple args. For example, instead of calculateVolume(int x, int y, int z)
, you may want to do something like calculateVolume(Point3D)
. Similarly, in your case, use an RGB class. It may seem silly, but it can save some annoying errors (e.g., if you have functions that take ints and RGBs), and time (if you have to pass the values to other functions). You can create a static factory method to make these types easier to create when passing arguments.
For example: doSomethingWithColor(RGB.create(20,30,40))