Reputation: 29996
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?
// T.hpp
class T {
public:
void foo();
private:
void helper();
};
// T.cpp
void T::foo() {
helper();
}
void T::helper() {
}
// 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
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:
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
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
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
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