6

As a novice C++ programmer I have always put my classes interface in .h files and implementation in .cpp files. However I have recently tried C# for a while and I really like its clean syntax and way to organize files, in particular there is no dinstinction between headers and implementation, you usually implement a class for each .cs file and you don't need headers.

I know that in C++ this is also possible (you can code "inline" functions in .h files), but up to now I have always seen a clear distinction between .h and .cpp files in C++ projects. What are the advantages and disadvantages of this approach?

Thank you

tunnuz
  • 23,338
  • 31
  • 90
  • 128

9 Answers9

10

There's a few ways that separating the two help in C++. Firstly, if you'd like to update a library without changing an interface then having the code in the C++ file means that you simply can update the library rather than the library plus the headers. Secondly it hides the implementation. That is, it forces people to look at your class only in terms of the interface, the thing that should concern them if the code is well written. Finally, there's a sort of asthetic cleanness with interface + documentation that comes with this separation. It's something you have to get used to but after a while it'll feel natural (opinion.)

wheaties
  • 35,646
  • 15
  • 94
  • 131
  • 2
    The "separating interface from implementation" argument is bogus imho. Yes, well-written code only concerns itself with the interface. But let's face it, using separate headers doesn't force anyone to write good code in this concern (unless you lock the implementation away, and even then someone *might* use undocumented APIs). It's like saying that Python encourages readable code by requiring some indentation. –  Nov 10 '10 at 15:37
  • 1
    @delnan there's very little that can be done to stop bad code other than code reviews. – wheaties Nov 10 '10 at 15:46
  • Nah, this is a bogus argument. This is possible just as well in a language like C#. Key feature is that class accessibility can be controlled at the module level, a feature that C++ doesn't have. Because of its compilation model. – Hans Passant Nov 10 '10 at 16:22
5

Don't forget build times.

Putting implementation code in header files makes them more likely to be changed. And changing header files will cause rebuilds of all the CPP files that include them, which in turn increases build times. This can be significant in larger projects.

I am also a fan of keeping the implementation hidden from users of my libraries. Unfortunately this doesn't work for template classes.

My rule of thumb: keep declarations in .H files, keep definitions in .CPP files.

dripfeed
  • 387
  • 1
  • 10
2

it's cooler to have the symbols defined at one place for the case you wanted to compound C++ with already compiled binaries (typicly when using a library). imagine you need to define external symbols for global stuff in your binaries. if you had .cpp and .h code in the same file you would have to define the symbols for your binaries for every such file. in two files way you could have just the one .h with definitions for binaries and a lot of .cpp files that use it.

Pyjong
  • 3,095
  • 4
  • 32
  • 50
1

The main difference is that something implemented inside a .h file will be placed in every compilation unit that includes that header, this will create redundancy during the compile phase in the final binary executable.. while splitting with .h and .cpp will compile it in a single object file that is later linked against the other objects files by having just one compiled binary code that implements that header file.

In addition if you declare things just inside a .h you are not able to share variables and structures between more other .cpp files..

Jack
  • 131,802
  • 30
  • 241
  • 343
  • The linker will remove the redundancy, so the final executable will not be larger. However, the combined size of all object files will be larger. – Sjoerd Nov 10 '10 at 15:25
  • A way to mitigate this problem is to put *everything* into .h files, and then have just one compilable .cpp that includes them all. (This won't work for a library, but will work for an executable.) – Kristopher Johnson Nov 10 '10 at 15:30
1

It's interesting to note that C# seems to be going in the C/C++ direction to some extent recently, with the introduction of partial classes.

The particular advantage of this in the IDE is that the Visual Studio designer will modify the part of the class that deals with visual controls, or data members, and their layout without any worries about mucking up the methods (application logic) that reside in a separate file.

Buggieboy
  • 4,636
  • 4
  • 55
  • 79
  • 1
    Partial classes are *not* just a separation of implementation. Declaration as well. There is no equivalent for it in C++. – Hans Passant Nov 10 '10 at 16:25
  • 1
    Partial classes are figments of the designer's imagination and only truly exist to split physical concerns of coding, such as the separation of tool-generated code. They don't exist past the point of compilation in the same way that header files exist. –  Nov 15 '10 at 13:00
1

I would echo @wheaties and add a few further items

  1. Compilation is easier (may be it's just me), I've never been able to get compilation to work just right if you modify the header only (as in all the implementation files that have included it). I believe in Makefiles you have to add the dependencies manually which is a real pain in very large scale projects (again could just be me). So if you have your code in implementation files, then changes simply mean recompiling that particular file - very useful when you want to do quick changes, build and test.

  2. Let me re-iterate the hiding aspect, most often you don't want people to know the implementation details due to the sensitive nature of the code, and thus only expose the headers plus the pre-built libraries, and the separation is key here.

  3. Forward declarations, neat trick where you don't need to include the implementation details of a class in the header file if it's not being "used" in any of the code in the header, but then in the implementation file you can include the real header and "it all works nicely" (helps if you have cyclic dependencies - why you have them is different issue!)

Nim
  • 33,299
  • 2
  • 62
  • 101
1

On a recent large project the authors of systems I wanted to use had placed a lot of the code in .h files. When including their .h files into my own source it added further dependencies to my file. After including the dependencies for their project I ended up with typedef collisions. If they had separated the code and only placed declarations in the .h file it would have been much simpler. I suggest using posix types and only putting declarations into .h files.

Jay
  • 13,803
  • 4
  • 42
  • 69
0

As for the comparison part of .cs versus .cpp/.h I think you need to keep in mind the background the lead architect of C#: Anders Hejlsberg. In Delphi you also don't have the distinction of header and module (ignoring include files for this discussion). You simply have two sections in a unit file initialization and implementation.

The other points were already mentioned.

0xC0000022L
  • 20,597
  • 9
  • 86
  • 152
0

I see that a lot of responses advocate separation, primarily for build-time and implementation hiding benefits. Both are definitely pluses, though I'll argue the counter example: Boost.

Most Boost libraries use a .hpp file with no external linking. The reason is that this is often required in the case of templates, when the compiler must know the argument types from the calling routine. So you might not have a choice if you want to stick with the "modern" C++ approach of shunning classes for templates.

chrisaycock
  • 36,470
  • 14
  • 88
  • 125
  • Templates are a different kettle of fish. The OP was, I think, referring to the practice *in general* of putting the implementation in the header file. – Moo-Juice Nov 10 '10 at 16:46