views:

186

answers:

2

Hi!

I have some functions that can be grouped together, but don't belong to some object / entity and therefore can't be treated as methods.

So, basically in this situation I would create a new namespace and put the definitions in a header file, the implementation in cpp file. Also (if needed) I would create an anonymous namespace in that cpp file and put all additional functions that don't have to be exposed / included to my namespace's interface there.

See the code below (probably not the best example and could be done better with another program architecture, but I just can't think of a better sample...)

Sample code (header)

namespace algorithm {
   void HandleCollision(Object* object1, Object* object2);
}

Sample code (cpp)

#include "header"

// Anonymous namespace that wraps 
// routines that are used inside 'algorithm' methods
// but don't have to be exposed
namespace {
   void RefractObject(Object* object1) {
      // Do something with that object
      // (...)
   }
}

namespace algorithm {
   void HandleCollision(Object* object1, Object* object2) {
      if (...) RefractObject(object1);
   }
}

So far so good. I guess this is a good way to manage my code, but I don't know what should I do if I have some template-based functions and want to do basically the same.

If I'm using templates, I have to put all my code in the header file. Ok, but how should I conceal some implementation details then?

Like, I want to hide RefractObject function from my interface, but I can't simply remove it's declaration (just because I have all my code in a header file)...

The only approach I came up with was something like:

Sample code (header)

namespace algorithm {
   // Is still exposed as a part of interface!
   namespace impl {
      template <typename T>
      void RefractObject(T* object1) {
         // Do something with that object
         // (...)
      }
   }

   template <typename T, typename Y>
   void HandleCollision(T* object1, Y* object2) {
      impl::RefractObject(object1);
      // Another stuff
   }
}

Any ideas how to make this better in terms of code designing?

+4  A: 

That's a pretty common solution. Boost does it, and I do it as well, but with the detail namespace instead. Just make it a rule: "don't look inside detail!"

File-wise, I recommend giving details their own file, and tucking it away in a detail folder. That is, my code would be akin to:

//           v
#include "detail/RefractObject.hpp"

namespace algorithm {

   template <typename T, typename Y>
   void HandleCollision(T* object1, Y* object2) {
      detail::RefractObject(object1);
      // Another stuff
   }
}

This is just good code practice in general (keep things split up and re-usable) and keeps the header file cleaner of implementation details.

GMan
+1  A: 

You can't hide your source from the user unless you're going to compile it first, which is impossible with templates. So I suggest, in a sense, that you don't bother.

Also gotta ask why Refract can't be a member method.

DeadMG
Member of what? Also, free-functions are preferred anyway. :)
GMan
Well, I stated there that this is just for sample. In case of my real project `algorithm` includes approximation algorithms and path-finding algorithms, so that it's just impossible to make them `members` in the meaning of that word...
Kotti
member functions > free functions since the invention of Intellisense.
DeadMG
@Dead: Absolutely not. Free-functions increase encapsulation and improve reusability (just to name a couple things) and are, in modern C++ design, the preferred option. Functions should be named well enough and consistent enough not to have to rely on Intellisense. :)
GMan
They should be, but they're not, and the fact that Intellisense exists and is such a great tool proves such. Happy to reduce encapsulation and re-usability in order to actually be able to use the function in question. The STL is especially bad at just dumping free functions in std, so that it's impossible to use without a reference up.
DeadMG