tags:

views:

342

answers:

7

So, I have a class. It's a useful class. I like a lot. Let's call it MyUsefulClass. MyUsefulClass has a public method. Let's call it processUsefulData(std::vector<int>&).

Now suppose processUsefulData really does two things and I want to refactor it from this:

std::vector<int> MyUsefulClass::processUsefulData(std::vector<int>& data)
{
    for (/*...*/)
    {
        for (/*...*/)
        {
            // a bunch of statements...
        }
    }

    for (/*...*/)
    {
        for (/*...*/)
        {
            // a bunch of other statements...
        }
    }
    return data;
}

Now, I want to split these responsibilities and rewrite the code as

std::vector<int> MyUsefulClass::processUsefulData(std::vector<int>& data)
{
    doProcessA(data, dataMember_);
    doProcessB(data, otherDataMember_);
    return data;
}

So, I don't know if I should make the two helper functions free functions or member functions, and when each would be appropriate. I also don't know if it's better to make them in an anonymous namespace or not. Does anyone know good times to do this?

+2  A: 

I usually make them protected or private member functions. It would depend on whether you plan on deriving the class and overriding the functions.

If they are common enough functions that they are used in other classes, move them to static functions contained in a common class or a separate object that your class uses.

Chap
A: 

Think about the scope. Are those functions going to be used in another class, or elsewhere? Should they be publically call-able?

It seems like they should be private member functions to me, but it all depends on your overall scoping structure.

Sev
+2  A: 

Always prefer free functions over member ones. See my answer here to know why.

Piotr Dobrogost
A: 

Member functions certainly if the original function made sense as a member function.

Private/protected IMHO depends on how their functionality is used: if the original function's operation is still required and the refactor is solely to make the code cleaner then make them protected or private and call them from the regular function. You get the refactor but keep the class's public interface intact that way.

Eric M
+1  A: 

The fact that you mention free functions leads me to believe that the 'bunch of other statements' do not require access to class data. If so, make them free. This reduces complexity of your class header, plus free functions are easier to use in the standard algorithms (maybe std::for_each since you're working with vectors anyway?).

Ryan
+4  A: 

I generally make helper routines "free" routines in an anonomous namespace if possible. That way I don't complicate the interface (off in the *.h file) with stuff clients don't need to worry about.

However, you have to be careful that you don't introduce non-reentrancy by doing that. For instance, by modifying global data objects or static locals rather than class members. If you need to do that, you are better off making it a proper class member.

T.E.D.
+2  A: 

Free function / member function

I would make them free functions is possible (they do not need access to the internals of the class). If they work on a set of attributes or need access to other members then make it a member function.

Access

If the code only has sense in this scope, and will not be used from other code then make them private: private if it is a member, or implemented in an unnamed namespace if it is a free function.

If other code will benefit from using the code then publish it in the interface. That means making it protected if it is a member or having the free function accessible through a header in a named namespace (or global namespace).

David Rodríguez - dribeas