6

I have a class that has 5 static public functions and 1 static private function (called from one of the public functions). The class doesn't have any member variables. It seems to me that it should be a namespace and not a class. But what to do with the private function? I prefer it not to be accessible by every namespace user, but there is no access control in namespaces.

Igor
  • 26,650
  • 27
  • 89
  • 114
  • +1 : Actually I'd rather see the question asked "static member classes vs. namespaces with static functions :> – Kornel Kisielewicz Jan 17 '10 at 12:29
  • There are different solutions, and it's hard to choose the best without knowing your goal. Are you attempting this deviant conversion to make everyone's life a bit harder, or to invent some new problem for yourself? – ima Jan 17 '10 at 13:13
  • I am doing this conversion because I think that if I want to have a group of related functions - it should be a namespace, and not a static class. Are there different opinions about it? – Igor Jan 17 '10 at 14:36
  • It depends on how private the private function is. Is there any harm in making it visible to users? If so, you've got something that needs to be encapsulated, so a class sounds justified. If not, just pack it away in a "detail" subnamespace or similar so it doesn't cause confusion. – jalf Jan 17 '10 at 19:36

4 Answers4

13

There are two ways i know of

Don't declare them in the header

One way is to not declare those functions inside the header. They can be placed into unnamed namespaces within the implementation file, only.

Indeed, you will then have to implement any function that accesses this private function in the implementation file (not inline in the header).

Put them into a detail namespace

Preferably, you put them in a different header, and include them. So the code of them won't disturb your interface header. This is how boost does it, too:

#include "detail/destroy.hpp"

namespace orbit {
  void destroy() {
    detail::destroy_planets();
    detail::destroy_stars();
  }
}
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • +1: for the boost reference -- I have a lot of "detail" code in my repos -_- – Kornel Kisielewicz Jan 17 '10 at 12:28
  • +1 I saw the second method in `boost` source code many times, but you have a better memory my friend ;) – Khaled Alshaya Jan 17 '10 at 12:29
  • I tend to use the `detail` approach too, Alexandrescu used a `Private` nested namespace in `Loki`. I would also like to point out the better encapsulation of implementation that comes with NOT declaring the functions in the header and resorting to a different header (meaning 3 files: `thing.h`, `thingImpl.h`, `thing.cpp`) – Matthieu M. Jan 17 '10 at 13:26
8

I don't think there is a solution to this :)

One -different- solution, would be to separate these functions into a separate compilation unit, then declare the private functions inside an anonymous namespace.

Khaled Alshaya
  • 94,250
  • 39
  • 176
  • 234
  • +1 An anonymous namespace in the implementation file is the way to go. Lately I've been doing this for previously non-static "private" that make sense as free functions to keep implementation details out of the header. – Adam Bowen Jan 17 '10 at 12:45
4

Keep the public declaration in the header file. Move the implementations to a cpp file. Mark previously private methods as static. This will make them unaccessible from a different linker objects (compilation units) and effectively hide them.

Marcin Seredynski
  • 7,057
  • 3
  • 22
  • 29
3

It seems to me it should be a class, not a namespace. Namespaces in C++ are primarily name resolution tools, and are not intended as the basis for design and do not really provide encapsulation. So I would leave it as it is.

  • Depends on how it is used, i have seen classes with static member functions used as a substitute for namespaces, say `string_util`. – Georg Fritzsche Jan 17 '10 at 12:33
  • @gf Indeed. But in this case he has a private member, which indicates to me he should use a class. –  Jan 17 '10 at 12:35
  • @Neil, yeah i think i sort of agree with you. But imagine `string_util` has private helper functions / classes. Would you consider keeping `string_util` as a class? I think i would still make it a namespace, and put the private functions or classes into `detail`. Rough rule for me: If it has data, make it a class. If it has only functions, make it a namespace. – Johannes Schaub - litb Jan 17 '10 at 16:37