I'm kind of new to large scale software development in C++, and I was wondering on the design side of things.

I was reading this question, and I thought that, overall, once we get past constant definitions and other trivial matters, C++ header files are just API definitions :

They define what other programmers (or yourself from other modules) will be able to use (classes, public functions), but no private class or function should be defined in it. It's like the header file defines the abstractions (interfaces ...) and the source file implements it. Once the source file is compiled, the implementation details are hidden away, and remain the publicly available headers defining what the module can do.

I felt this view of header/source file separation was a lot easier to understand and follow than the usual explanations, since you can just think "would XXX be publicly available API material, or is it a sausage-making detail to be hidden away in an undisclosed source file ?"

Is my mental model of header files roughly correct ? What did I miss ?

  • Also look at UML for a system created to help design software - its classes show API methods and data (attributes) in the class diagrams – gbjbaanb Sep 22 '15 at 15:41
  • Oh believe me, I know about UML ! =p It's just the C++ way of thinking I have trouble wrapping my head around. I "come from the Python world", with all the biases of thinking "Why would a language need header files ?" =) – Jiby Sep 23 '15 at 7:49

It's not a bad mental model to use as a guide but unfortunately for historical / technical reasons C++ headers conflate interface and implementation in ways that this simple mental model doesn't fully capture.

In order to make good physical design decisions when things get a little more complex, it is generally necessary to understand the way headers work in C++ at a more detailed level.

To give an example: from your API view, a header file should not include the definition of a private implementation class. In practice however, such class definitions will often appear in a header file since the compiler will need to know their size if they are contained in any public classes. Techniques exist to break this kind of dependency but they generally impose a cost in terms of code complexity, performance or both. Understanding when it's appropriate to use one of these techniques requires a deeper understanding of how headers work in C++.

  • I was thinking about the forward definitions of private classes : can we cheat around by putting them in a separate "hidden" header file and include them ? This way you would keep the "plain API header" and an "dirty private tricks" one. Not sure it would do much good though. – Jiby Sep 23 '15 at 7:47
  • @Jiby A separate "detail" header is quite a common way to split out private implementation details so yes, that can be a good approach. It's also quite common to put implementation details in a nested detail namespace so they don't pollute the main library namespace and to make it clear they are not intended to be used directly. – mattnewport Sep 23 '15 at 14:15

Pretty much, there's little difference between a header file and an interface as used by other languages for the main part. Obviously though there are differences in implementation in that the header will also contain private information, but fundamentally they are used to describe the features the class or module will provide.

In a way then, its also a mental model of data structures combined with the API so it can be more useful when you're doing the kind of initial design you describe.

Ideally a header defining an API would contain just the pure interface but as C++ doesn't have an ABI, this doesn't really matter. If you build a higher level system that does provide a pure client interface, you'll be using a different mechanism such as an IDL or WSDL to define that anyway.


Header file as a pure interface works more or less fine with classes. As soon as templates come into picture, this model stops working whatsoever. Templates are not compilable, and the whole template implementation must appear in the header.

  • Can we cheat around by writing template related code in a separate header and including it ? – Jiby Sep 23 '15 at 7:49

There exists a mistaken understanding that "the header contains the declarations and constants, the implementation file contains the implementation".

No. A header file should contain anything that is to be used outside the "module" == compilation unit. It is the interface between the "module" and everything else. It is what a user of your code needs to read and understand in order to use it and nothing else.

Thus any classes or functions that are part of the implementation of that interface go to the implementation file. They are complexity for which we don't want to make the user pay in cognitive terms.

To further the point, any exposed interface (declarations in the header) will get used by someone somewhere, so we can never change it without breaking distant code. Ask Scott Meyers!

As a sidenote, api documentation (/*This function fudges widgets if provided those params.*/) go to the header. Implementation documentation (/*Using Shalqlq's algorithm to fudge widget memory state.*/) go to the implementation file.

As a second sidenote, because the language prior to C++20 doesn't support python/Rust style modules, the pImpl idiom can be used to enforce the above. It's disadvantages are boilerplate code and pesky debugging.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.