views:

212

answers:

6

Hi!

I have a working prototype of a game engine and right now I'm doing some refactoring. What I'm asking for is your opinion on usage of the following C++ coding patterns.

I have implemented some trivial algorithms for collision detection and they are implemented the following way:

Not shown here - class constructor is made private and using algorithms looks like Algorithm::HandleInnerCollision(...)

class Algorithm {
   // Private routines
   static bool is_inside(Point& p, Object& object) {
      // (...)
   }

   public:
      /**
       * Handle collision where the moving object should be always
       * located inside the static object
       *
       * @param  MovingObject & mobject  
       * @param  const StaticObject & sobject  
       * @return void
       * @see
       */
      static void HandleInnerCollision(MovingObject& mobject, const StaticObject& sobject) {
         // (...)
      }

So, my question is - somebody advised me to do it "the C++" way - so that all functions are wrapped in a namespace, but not in a class. Is there some good way to preserve privating if I will wrap them into a namespace as adviced?

What I want to have is a simple interface and ability to call functions as Algorithm::HandleInnerCollision(...) while not polluting the namespace with other functions such as is_inside(...)

Of, if you can advise any alternative design pattern for such kind of logics, I would really appreciate that...

+1  A: 

Yes, you can use unnamed namespace:

namespace
{
   int private_variable;
}

int f()
{
   return private_variable;
}

private_variable will be seen only inside current translation unit.

But generally I do not think it is a good idea. Better use classes, OOP, components. :) The higher is better. That's the modern C++ way.

topright
What? The modern C++ way is absolutely *not* to cram everything in classes, *or* to fixate on OOP. That is the "C with classes" way, and it hasn't been modern for 15 years.
jalf
IMHO, classes and components don't make sense if there is no instance storage, so this looks like a case where a private namespace is justified. `Algorithm` doesn't look like a case for a Singleton. So when you say "I do not think it is a good idea", what alternative, preferably with an example, is better? And what does "the higher is better" mean? The higher what?
Mike DeSimone
What i think is that in my case it actually doesn't have anything to do with the 'OOP' thing. I was asking for a way to logically group / wrap somehow-related functions without involving a class :)
Kotti
What I meant that if you want a "private function" it is better to use classes than simulating it via namespaces. The higher abstraction is better (for program design and programmers). I agree that OOP is not the only preferable high-level approach, see also functional and generative programming for many tasks.
topright
+2  A: 

There are a couple of idiomatic ways of doing this. The first way is, where there are implementation files (cpp files) simply use an unnamed namespace in that file for global functions or variables. Unnamed namespaces are not really unnamed, but instead have a unique name in each translation unit which you can't type. If you're functions are inline in a header file then you can't do this - the common approach seems to be to use a namespace named detail inside your feature namespace. This is not really private, but it is common enough for devs to leave well alone.

One thing you should note - the function is_inside in your example is marked in the comments as private, but it is not actually private. By default struct members are public - in fact this is the only difference between structs and classes, so because you don't precede it with private, it is public.

Stewart
I'm not sure, but the solution with 'detail' namespace seems cool, thanks.What about the struct - this is a problem of copying, because in actual code the Algorithm struct has some nested classes, that implement different sort of algorithms. Anyway, thanks for pointing.
Kotti
+1, but note that using a detail namespace will avoid polluting the global namespace, but it will pollute the `detail` namespace. If you have an accompanying implementation file, then keeping the auxiliary code within an unnamed namespace is a better solution to avoid name collisions.
David Rodríguez - dribeas
I think what was meant to be used is something like `namespace algorithm { namespace detail { ... } }`And in this case the only namespace polluted is the nested `algorithm::detail`, what is actually what we want to get :)
Kotti
@Kotti - yup - that is what I meant. Should have given an example :)
Stewart
+1  A: 

Well, to answer your initial question, to "privatize" a function, you either use static if you want it to be local to that file, or you can put it in a private header file if you want to use it throughout your code. I.e., either have static bool is_inside(const Point& point, const Object& object); in your .cc file or put the declaration inside of algorithmsPrivate.hh.

However, really, you're writing C-like code here. If you want to do it the C++ way, you would instead add a method to the Object class:

class Object {
   ...
   bool contains(const Point& point) const;
}

One nice thing about this is it would even allow you to make the function virtual.

virtual bool contains(const Point& point) const;

Then as you implement each Object, it can have its own implementation of the contains function.

clahey
Guess I could use this 'static' inside a compilation unit technique, but I actually liked the 'detail namespace' solution.Also, this is_inside was actually a stupid example, and real code doesn't have this function anyway. I just wanted to say that there are some algorithm-specific private routines, that can't be implemented via virtual functions in classes or smth like that.Thanks for your answer
Kotti
I like the detail namespace solution also.
clahey
+2  A: 

You can have the functions you want visible in one namespace and then have the functions like is_inside() in another namespace such as:

namespace othernamespaceHelperFunctions 
{
  ...helper functions... 
}

Just have the namespace you want to use be the only thing that uses the helper function namespace.

Mike Webb
+1  A: 

If the various functions have something to do with each other, if it's more than helping but really have a common factor such as acting on the same entity, then put them in a class. On the other hand, if a function acts on the same entity as others, but you also want to reuse it for other entities that are convertible to the first entity then extract it outside of the class:

bool same_size(const shape& a, const shape& b)
{
    return a.bounding_x == b.bounding_x && a.bounding_y == b.bounding_y;
}

The above function will work with any two objects that are convertible to or descend from shape.

Put functionality that you don't want to share with other translation units (i.e. helper functions and help objects) in an unnamed namespace. This is the C++ equivalent of the C static functions, and it instructs the compiler to keep anything inside the unnamed namespace private to this translation unit.

namespace {
bool is_inside(Point& p, Object& object)
{
    // ...
}
// ...
}

Put all the functionality that you want to share with other translation units in a named namespace. This will instruct the compiler to wrap the code with a common name, so names don't collide with external code (libraries etc.) names.

namespace kotti {
void HandleInnerCollision(MovingObject& mobject,
                          const StaticObject& sobject)
{
    // ...
}

// ...
}
wilhelmtell
Well, this is cool)
Kotti
Sorry for a probably stupid question, but is there any actual difference between writing `namespace { (private functions) }` and simply defining these functions in .cpp unit before the `namespace Algorithm { ...` declaration (so that they aren't visible anywhere outside that unit)?
Kotti
If you place the functions outside a named or unnamed namespace then you're placing the functions in the global scope. This means they will be visible to other translation units. The only way to hide free functions from other translation units is by placing them in an unnamed namespace. That's the C++ way of doing things (in C you'd make the functions `static`).
wilhelmtell
Also, you probably want to share the same namespace across translation units, rather than have each translation unit create its own named namespace. It will make your code less confusing (in which namespace is function `foo()`?) and less verbose, while still avoiding name-collisions you can't predict.
wilhelmtell
Is there some reason to not have the functions be static in C++?
clahey
From section 7.3.1.1, paragraph 2 in the standard: _"The use of the static keyword is deprecated when declaring objects in a namespace scope, the unnamed-namespace provides a superior alternative"_. See http://stackoverflow.com/questions/154469/unnamed-anonymous-namespaces-vs-static-functions
wilhelmtell
A: 

I think you should keep it as a static class. It gives you the benefits of public/private, which you desire, and I see no downside. I've always considered it something of a hack to use namespaces the way the other answers are suggesting. In my view, namespaces are for grouping related classes and free functions, and for preventing name collisions, not for providing encapsulation.

rmeador
`struct Algorithms { static void Function(); }; Algorithms algorithm; //What does this mean???`
Dennis Zickefoose
If the choice is the class with only static methods, I'd private the constructor so that `Algorithms algo;` code would make no sense. And where you need it, you would access your static members as `Algorithms::Function(...)`
Kotti
So now you have a solution that requires more effort on your part to get right, just so you can use a class. Additionally, if you need private functions, you either include them in your primary header, or create a second static class [with its own private constructor] in your implementation file. So now you're emulating both the named and the unnamed namespaces. There's simply no point.
Dennis Zickefoose