tags:

views:

322

answers:

6

What is your rule for which functions that operate on a class should be member functions vs. nonmember functions? For example, I have a class which represents a maze using a matrix of bools. I am making a function called isConnected which verifies that 2 points in the maze are in the same region (i.e. it is possible to travel from A to B).

Should this be member or nonmember? What is a good rule?

+2  A: 

I always refer back to FAQ 13.9. It's not an exact science but one based on discretion.

It is an oversimplification to say that whenever you need access to the class internals -- you should use a member. Notable examples are the stream insertion/extraction operators (>> and << respectively) and the binary +.

In your example, isConnected is a method to test the object's state i.e. an inspector and an ideal candidate for being a member.

dirkgently
+4  A: 

In this case, I would go for a member function. The rule I follow is that if a function has to access something that is internal of the current state of the instance, then it should be part of the "realm" of the class. In this case, the connectedness of A and B depends on the state of your object instance.

Of course, you could end up having a class having too many responsibilities. In this case, the keep it simple factor kicks in and you should consider if your class is trying to do too much. It would then be convenient to have a separated class (like, in your case, a ConnectednessEvaluator) whose specific role is to hold algorithms that can traverse and act on your Maze instances.

Stefano Borini
+9  A: 

When to make it a member function:

  • when the function is logically coupled with the class (like your maze connectedness example)
  • when the function needs to access private or protected members, it's better to make it a member than a friend.

When to make it a standalone function

  • when it's a generic function that can be templatized to naturally work on other classes (look at the <algorithms> header for good example)
Mr Fooz
A: 

The only stuff I tend to make non-member functions are things that are only called from within member functions (don't need to be visible outside the class), and can operate just fine on the class' public members and/or a small number of parameters.

T.E.D.
+2  A: 

Herb Sutter says "we want to make them nonmember nonfriends if reasonably possible", and he's smarter than I am.

http://www.gotw.ca/gotw/084.htm

Mark Ransom
There is also http://www.ddj.com/cpp/184401197 saying much the same thing
jalf
I agree completely... and I didn't even know that Sutter recommended this.
D.Shawley
A: 

Well, there are arguments for both.

In favor of nonmember functions:

  • It offers better encapsulation
  • It allows better code reuse (std::find can be reused for any container type, because it's a free function. If it had been a member, ever container would have to define its own)
  • It makes a lot of generic programming tricks easier. (container.begin() is not valid if container is an array. That makes it a bit more awkward to write generic code working on containers. But begin(container) can be made valid for any type, even built-in ones like arrays). It can also make mixins through composition a lot cleaner, because it doesn't require the user to "dot" yourself through members to get to the mixin object you want to operate on.

In favor of making things member functions is:

  • It's familiar. Java and C# requires this, and in a lot of programmers' eyes, member functions are synonymous with OOP.

and... that's it. (But that argument should not be underestimated. Code readability is important, and if people find it easier to read the member version, that's a strong argument in its favor. It just doesn't produce better code. From a strict "better code" point of view, nonmembers should be preferred when possible.

jalf