开发者

Using C++ headers (.h) vs headers plus implementation (.h + .cpp), what are the disadvantages?

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 ap开发者_StackOverflow社区proach?

Thank you


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.)


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.


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.


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..


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.


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!)


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜