2

Possible Duplicate:
Namespace + functions versus static methods on a class

Where is the most sensible way to write, for example, a function that would look like

Point intersection(const Line &L1, const Line &L2);

(assuming I have written classes Point and Line)?

Maybe I can make the question a little more precise: I am considering the following options:

  1. Write a global function (declare it in line.h, write it in line.cpp)
  2. Write a static method of the class Line
  3. Use a namespace.
  4. Write instead a function Point Line::intersection(const Line & otherLine);

I'm not a fan of the last option because I don't want my function to be "asymmetric" (I have several other examples of functions like this in my code). For the moment they are global functions (as in option 1.), but I'm given to understand this is not "good practice". As for static methods and namespaces, I am not acquainted to these yet, so I'm not sure.

What do you think is the "best" design?

Thanks for your insights!

Edit: To give you an idea of the size of my project : 50 to 100 classes.

Community
  • 1
  • 1
Seub
  • 2,451
  • 4
  • 25
  • 34

2 Answers2

3

It really depends on what you want to do. If you are just writing a very small program, I don't really see anything wrong with writing it as a global function. However, if your program is at least moderately sized, I would recommend using a static method, because you would be grouping its functionality with the class it deals with.

Of course, you could also do that with a Namespace. However, I imagine that you would have a Line class anyway, since it seems like it would lend itself well to an object oriented style of programming. With that in mind, I don't really see a reason to make it a namespace instead of a static method of class Line. That's certainly where I would look first if I were looking for an intersection method!

I don't see anything wrong with the last option either, but I prefer #2.

Richard Fung
  • 1,020
  • 6
  • 14
  • An alternative would be to go with #2 but reverse the classes. Just depends on your design. Point Line::intersection(const Line &L2); // L1 is the line object you're making the call to – MichaelH Jul 08 '13 at 21:29
  • Thanks, I think I'll probably use static functions then. – Seub Jul 08 '13 at 22:39
3

If your project is small enough to use names like Point and Line without enclosing them in a namespace, then it is OK to do the same with an intersection() function. Note that overload resolution means that you probably won't have any name clashes on the function name (but maybe on the class names).

If your project is of non-trivial size, then it would be worthwhile to put both classes and the intersection() function in a--the same--namespace. Argument Dependent Lookup means that clients of your classes will get the intersection function whenever they use objects of type Line as arguments:

void f( MyGeoLib::Line l1, MyGeoLib::Line l2)
{
    MyGeoLib::Point p = intersection( l1, l2); //just works
}
dhavenith
  • 2,028
  • 13
  • 14
  • Thanks for that. What do you think about static methods though? – Seub Jul 08 '13 at 22:37
  • 1
    I think in this case a static method is in fact counter-intuitive. Intersection is "like an operator". Having to qualify every call with the class name (`Line::intersection( l1, l2)`) is not intuitive to me. One good reason not to make this a member (be it static or not) is that you may want other overloads that don't have identical argument types: is `intersection( Line, Surface)` supposed to be part of the Line or of the Surface interface? My answer would be: neither, it is an interface of your geometry library. – dhavenith Jul 09 '13 at 10:11