Rules of thumb for putting functions in header fil

2019-04-26 20:32发布

问题:

Lately I have started to put more and more functions into header files, mostly for convenience. But I fear I might be overdoing it, my headers are full of includes and I'm not sure if that's a good idea.

What are your rules of thumb for moving functions out of or into header files?

In case you're wondering, I'm talking about developing applications, not libraries.

Edit:

I guess it's helpful if I outline the pros/cons of inline (naturally) header functions versus implementation functions from my point of view:

Pro inline:

  • More clean/concise.
  • No need for signature duplication.
  • No need to change any Makefile to link against new files.
  • Instant ability to introduce template parameters.

Contra inline:

  • Increased compile time (I don't care that much)
  • Many includes in headers (Shouldn't be such a big issue if they use guards)

According to that, it seems like a good idea to put pretty much every function in headers, and I believe that's pretty close to what the STL and Boost are doing (although those are libraries, as opposed to my code).

回答1:

One of my most inviolable rules: only function bodies which are inline are allowed in header files. Anything else is asking for trouble with multiple definitions in the link phase.

Headers should be left predominantly for declarations rather than definitions. I have exceptions to that rule (being the flexible type) but none of them involve non-inlined function bodies.



回答2:

My rule of thumb is "Not in the header, unless you have to." And as for convenience, do you find increased compilation times convenient?



回答3:

There are a few obvious technical aspects - templates and inline functions must be in headers - headers included from multiple translation units must be wary of the One Definition Rule - more bluntly, you'd want a bloody good reason to even consider putting an out-of-line function implementation in a header, and I can't think of any times I've even been tempted.

So, the question boils down to:

    inline in header versus out-of-line in implementation file?

Factors:

  • you say you're designing application level code not libraries, so you don't (currently) have to worry about other teams getting dependent on your code, nor minimise their need to recompile (versus just relink) by keeping implementation out of line
    • BUT if you're writing good code that has any potential to become useful to other teams, then you might find yourself wishing you'd kept implementation private
  • inline versus out-of-line typically represents about an order-of-magnitude overhead for trivial data get/set functions... if you have functions that are called repeatedly from performance critical code, then you've reason to prefer inlining
  • in-header implementation (especially if intermingled with the declarations) can often obfuscate the API, but sometimes actually makes the code more self-documenting
  • localisation and removed redundancy (of combining declaration/definitions) definitely removes potential for typos/errors and can often improve productivity

Bottom line: if you're finding yourself doing it more and more, then it's obviously working for you and there's no particular reason to think you're about to get burnt. Keep an eye out for the potential issues but don't over-engineer the heck out of stuff based on some hypothetical and unlikely-to-materialise concern.



回答4:

A good coding standard will tell you to implement methods and functions in the source (cpp) file.

If you prefer it, you can implement templates and inline functions in the header.



回答5:

Since this has been tagged as C++, why don't you seperate them into logical classes?

Normally I have one class declaration in a header file and it's definition in the corresponding source file.



回答6:

The two rules I use are

1) If it's an inline functions

2) If it's a template function.



回答7:

First, template function must be put in headers.

Besides, functions with an empty body, such as a default constructor or default but virtual destructor may be put in headers.

I never use inline because compiler don't guarantee that.