2

If I write a class with no forward declaration, why do I need to break it up in to .h and .cpp? Is there anything wrong with just using inline declarations and keeping it all in one file, and just including that where I need it?

SRobertJames
  • 8,210
  • 14
  • 60
  • 107
  • Have a look at `header-only library`. Also relevant : http://stackoverflow.com/questions/12671383/benefits-of-header-only-libraries – Seçkin Savaşçı May 26 '15 at 23:04
  • What makes you think you need to? Have you even tried doing it? – luk32 May 26 '15 at 23:05
  • There's no issue with mashing everything together like this, provided you are sure you'll never want those classes again. If you ever wanted to use these classes in another program, you would have to copy+paste the code rather than just #include it. – Will May 26 '15 at 23:05
  • 2
    @Will Why would you have to do that? If it is all in a header than it can be included into any program... – Fantastic Mr Fox May 26 '15 at 23:06
  • @Ben Right, if it's all in header file, it can be included anywhere, but if he does not (Which I think is what he's asking about), and all the classes and main() are in one .cpp, it cannot. Is this correct? – Will May 26 '15 at 23:10
  • 1
    @Will a big issue is compilation time. Header files have to be processed for every compilation unit that includes them. If you're looking at a 2+ million line code base with 10k+ files (like the one I'm working on) this becomes **very** significant. – 3Dave May 26 '15 at 23:12
  • Also, inlining itself comes with a potentially crippling cost. There is a reason that it is not default behavior. – 3Dave May 26 '15 at 23:14
  • @DavidLively `inline` will cost in executable size and compile time but benefit code speed. Plus the compiler wont always inline everything you tell it too. – Fantastic Mr Fox May 26 '15 at 23:21
  • @Ben that's not always true. Inlining increases code size, which can interfere with code caching - huge execution speed penalty / pipeline stall, especially if you're calling an inlined function or method in a loop (probably fixed-iterations or it wouldn't get inlined despite hints.) – 3Dave May 26 '15 at 23:51
  • 1
    @DavidLively yes, but i would say in a general case on a modern machine the combination of 1. The compiler not in lining complex code and 2. Large cache memory on processors means that this wouldn't happen often. If you have a 32Kb cache and you have a loop with inline functions that operate on massive arrays then maybe. But i feel like something has been done incorrectly if we are at this point? – Fantastic Mr Fox May 27 '15 at 00:00
  • @Ben In most situations I would agree with you. But, performing complex operations on large datasets isn't exactly uncommon. 32KB of code is about 8000 32-bit instructions, which isn't really all that much. When you start throwing multi-threading into the mix where that 32KB is shared with multiple processes, your cache starts to look pretty small. – 3Dave May 27 '15 at 12:49

2 Answers2

6

One of the issues with everything inline is the fact that whenever you change the implementation, all clients of your class have to recompile. If you put the implementation in a .cpp file, then only the .cpp has to be recompiled (and linked), provided you don't change the interface (i.e. the header file).

This issue becomes serious in large scale C++ projects, and that's why the PIMPL idiom was invented.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • “After all, what we’re doing is (somewhat artificially) splitting each object into two halves for the purposes of hiding one part.” — Well, that's the definition of a Horcrux. (sorry) – KPM May 27 '15 at 07:13
3

There is nothing wrong and it's perfectly legal from the language point of view. Although, it comes with a cost. The files have to be parsed and processed every time project gets recompiled. This is a serious issue for large projects.

The pimpl idiom (which is based on forward declarations) was introduced to reduce compile time for large projects. There even is an example in the standard library for this, namely iosfwd.

On the other hand there are cases where everything is in headers. That is because pretty much everything that is a template has to be placed in headers. Moreover the templates put quite a performance strain on the compiler, there is a lot of logic going on. Despite this, there are quite stellar examples of header-only libraries based on templates, like Eigen or big portion of boost.

luk32
  • 15,812
  • 38
  • 62