5

I have most of my classes separated into two files (.h and .cpp). All of their methods (public, private or protected) are declared in .h file and defined in the .cpp file.

However, sometimes I just need a quick helper method that is used by only one of the member methods. In these cases, is it ok to just declare/define this method in .cpp file as a non-member function without declaring it in the .h file?

What are the possible cons of this approach? The one I see is that the definition of this method has to come before its usage in .cpp file (if we don't want to use forward declaration). Also IDE might have troubles finding these functions if they are entirely in .cpp file.

The reason I am asking this is that sometimes it almost feels like I am polluting .h file with declarations of these methods that do not access member data and are not used by any other class/file. It looks like I am making the really important declarations in .h file harder to find/read by introducing these helper method declarations.

mk33
  • 351
  • 1
  • 2
  • 6
  • 5
    It is fine, a good idea, and much preferable to having private members. Just put them in an anonymous namespace. – juanchopanza Dec 07 '15 at 21:21
  • 1
    Your IDE shouldn't have any problem finding the declaration and definition of a free-standing function in your cpp file. – Klitos Kyriacou Dec 07 '15 at 21:22
  • C's solution was to make function (non-member) static in the .cpp file: That would also work here – rts1 Dec 07 '15 at 21:23
  • I do this. I put the function in the cpp directly above the member function that actually uses it. But your concern here is the ugly header, which you can solve with an interface class. – Kenny Ostrom Dec 07 '15 at 21:33

3 Answers3

4

Using a non-member function is the better solution. Some even prefer non-member functions to public member functions if that can be achieved. See Scott Meyer's article on the subject.

In days long past, I used to make the helper functions static functions in file scope.

For a few years, I used anonymous namespaces in .cpp files and put the functions and any helper classes in the anonymous namespace.

namespace
{
   // Helper class(es)
   struct Helper
   {
      ...
   };

   // Helper funtions
   type1 function1(...) { ... }

   type2 function2(...) { ... }
}

The anonymous namespaces were a problem when I wanted to use the type_info of the helper classes in messages. To overcome that, I have adopted a new method. Use a namespace that corresponds to the .cpp file.

foo.cpp:

namespace fooNS // Just append "NS" to the name of the cpp file
{
   // Helper class(es)
   struct Helper
   {
      ...
   };

   // Helper funtions
   type1 function1(...) { ... }

   type2 function2(...) { ... }
}

using namespace fooNS; // This allows the helper classes and functions
                       // to be used in the .cpp file without explicit use
                       // of the namespace.

As of today, I would recommend the last method for helper classes and helper functions.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • I like your answer. However, adding NS to the end of the namespace smells like a variant of Hungarian Notation. Why do you do it? I would make the name more descriptive and call it "namespace localFoo" (or maybe internalFoo). But what I actually do is just use anonymous namespace. That's the only namespace name that's guaranteed to be unique. – Klitos Kyriacou Dec 07 '15 at 21:40
  • Personally I prefer anonymous namespaces, but when I end up naming the namespace with utility functions, I use `detail` or `secret`. One specific reason why named namespaces could be better than anonymous namespaces, is that the latter can very easily lead to name conflicts if a project decides to use [unity builds](http://engineering-game-dev.com/2009/12/15/the-evils-of-unity-builds/) to speed up compilation time. – Akos Bannerth Dec 07 '15 at 21:44
  • @KlitosKyriacou, using `foo_detail` or `foo_private` is good too. I decided on using "NS" probably because I was only concerned with the name being unique that didn't require too much thinking to come up with. – R Sahu Dec 07 '15 at 21:45
1

You are on the right track indeed. There is no shortage of articles describing why one should prefer non-member methods to members.

On of the most important of the benefits is that it decreases coupling.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
0

It is ok as long those helper function declarations do not produce name clashes with names from other header files, but this is not something that you cannot handle.

A better approach is to use anonymous namespace , and an even better approach is to use namespaces. That way you can be specific and do much more, e.g. versions or even link the to a specific class:

namespace foo_helper{ foofun(){} }
class foo{ 
// calls foo_helper::foofun()
};

Finally you can use lambda functions for trivial tasks within a method to do grouping.

g24l
  • 3,055
  • 15
  • 28