NoSenseEtAl
NoSenseEtAl

Reputation: 29996

Where should I implement this "private" helper function?

My class definition is spread across headers and source files:

// T.hpp

class T {
   public:
      void foo();
};

// T.cpp

void T::foo() {

}

If T::foo needs to make use of some helper function that need be visible only to T, which of the below solutions is best?

1. Private member

// T.hpp

class T {
   public:
      void foo();
   private:
      void helper();
};

// T.cpp

void T::foo() {
    helper();
}

void T::helper() {
}

2. Free function accessible only in class definition's TU

// T.hpp

class T {
   public:
      void foo();
};

// T.cpp

namespace {
    void helper() {}
}

void T::foo() {
    helper();
}

Is there any difference except that with the former I will end up with more functions in the header file?

Upvotes: 12

Views: 14010

Answers (4)

bames53
bames53

Reputation: 88155

Free functions that need access to private members would require friend declarations in the header anyway, so they're probably not better than private member functions.

Functions that don't need private access should be free functions whether they're declared in the header or not.

So if they need access to private members then make them members. Otherwise make them free functions.

Scott Meyers has this algorithm for deciding whether a function f related to a class C should be a member, friend non-member, or non-member non-friend:

http://drdobbs.com/184401197

if (f needs to be virtual)
   make f a member function of C;
else if (f is operator>> or
         operator<<)
   {
   make f a non-member function;
   if (f needs access to non-public
       members of C)
      make f a friend of C;
   }
else if (f needs type conversions
         on its left-most argument)
   {
   make f a non-member function;
   if (f needs access to non-public
       members of C)
      make f a friend of C;
   }
else if (f can be implemented via C's
         public interface)
   make f a non-member function;
else
   make f a member function of C;

Upvotes: 7

Alek86
Alek86

Reputation: 1559

yes, there is a difference

if the functions are not parts of the class, it would be better if they are not tied to this particular class:

  • there is a probability you will want to use them in another class, and in this case it will be very easy to move them in some shared place and use in both classes

  • if the function (which could be a free one) takes a thirdparty class as a parameter and if you make it a member function, you must either include another .h file (which has this class definition) or declare this class in your .h file. this means more coupling, which is bad :)

so I would prefer to write them as free ones (maybe in .cpp file in unnamed namespace, if they aren't (and, probably, won't) used in other classes)

Upvotes: 1

wilhelmtell
wilhelmtell

Reputation: 58667

Prefer free, non-friend functions over member functions, because these have less access to class members than member functions, and therefore have less of a chance to introduce bugs.

If the function is completely outside the interface scope then also put it in an unnamed namespace in the implementation file. This will reduce the chance of bugs even further, because other translation units will not be able to call the function.

Another advantage you get with a non-friend in an unnamed namespace is that there's less of a chance you change the header (since there's one less entity in there). Changing a header file often slows down build times considerably, because of the compile-time dependencies. Private or not, you'll probably have a number of translation units depending in terms of compilation on everything in the header.

Upvotes: 10

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385098

As far as I can tell, you've pretty much got it. There's no difference other than your header file will needlessly grow. You may also be leaking some implementation details in your class's API, though.

Upvotes: 1

Related Questions