How to include WinAPI without contaminating the rest of the code? - c++

I'm working on a library in C++ and a part of it is an abstraction layer of several OS functions that i need. I started implementing that with the Windows API but plan to add support for other platforms with #ifdef and such.
What is however starting to become a problem is that including Windows.h propagates to the whole rest of the code where i don't need it and especially, as it is a library, it will also contaminate the code of other people that would use it. I wouldn't really mind if the Windows API used a namespace or some clear way to distinguish its code but instead they #define a lot of pretty common words such as small, near, far (lowercase) and a lot of the function names are also pretty general.
So i would really like if only the platform specific part of my code had access to these and it wouldn't be included anywhere else. I know that the obvious solution would be to only include Windows.h in the CPP files but that isn't always possible because some of the platform specific data types or structures are class member variables such as:
class Window {
public:
// ...
private:
HWND handle;
};
So is there a way to accomplish this?
Thanks.

Use the pimpl idiom ( http://en.wikipedia.org/wiki/Opaque_pointer ). Limitations of the C++ programming language makes it necessary to use tricks like this in order to get information hiding.
One of the ways of doing that is doing it the same way as you would in C (where you don't have that problem at all, because of the following): Forward-declare a struct in the header file and define its contents in the implementation file.
Most people do that by extracting the entire private part of your example into its own struct, whose contents is only defined in the implementation file, and only put a pointer to it in the header file, as the now only member of the private part of the class.
also, #define WIN32_LEAN_AND_MEAN before the #include in order to strip down what the windows.h gives you.

Related

conditionally integrate functionality from one header into another if it's included (is this even necessary?)

Maybe I'm thinking about this the wrong way because I spent so many years on C# away from C++ and I'm a bit rusty. I forget how good selective linking is.
This is really a multi-part question, and I'll start by describing the big picture.
I am building a JSON parser and query engine for low memory environments like IoT devices. They don't have a ton of space for code so I want the end developer to be able to only include parts of my library they intend to use. The pull parser is the core of the library so that's a given, but you might not need the in-memory trees.
Currently, lacking a better way, I have a #define HTCW_JSONTREE which i define in one header. It gets picked up by a 2nd header and a function is included in the 2nd header that depends on code in the first header.
#include "JsonTree.h" // optional
#include "JsonReader.h" // if JsonTree.h above is included
// extra functionality will be available from JsonReader
basically a parseSubtree() function that returns an in-memory tree will be available if you include both headers, but won't if you don't include JsonTree.h. It smells.
First of all, is this necessary, or can I just unconditionally include all the functionality and expect that parseSubtree() will never get linked in if its never used?
Second, if it is necessary, what is a better way to do it? Right now the includes are order dependent and the code reeks. I want to change it. Basically it's just in there now until I figure out something better because it's easier to remove than it would have been to add later if it turns out i need it.
Thanks in advance.
Here's more of what the code looks like:
From JsonTree.hpp by way of JsonTree.h:
#ifndef HTCW_JSONTREE_HPP
#define HTCW_JSONTREE_HPP
#define HTCW_JSONTREE
#include <cinttypes>
...
from JsonReader.hpp by way of JsonReader.h:
#ifdef HTCW_JSONTREE
JsonElement* parseSubtree(mem::MemoryPool& pool,JsonParseFilter* pfilter = nullptr,mem::MemoryPool* pstringPool=nullptr,bool poolValues=false) {
...
#endif
Where JsonElement comes from JsonTree.h as well. parseSubtree is my integration point between the two areas of functionality
First of all, is this necessary
Absolutely not.
Or can I just unconditionally include all the functionality and expect that parseSubtree() will never get linked in if its never used?
You totally can. That's how all libraries in existence have worked from day one.

How to abstract your code from platform specific header file

Hi I am trying to find a way to prevent the inclusion of platform specific header file for example windows.h.
Curiously none of the solution I found are not satisfactory to me. Maybe it can't be achieved.
I think to achieve this goal several technique need to be used. And there is a lot of example on internet but I couldn't found any about one aspect. Something has to talk/create to your abstraction. Here is an example:
This is a really simplified version of a render window render target.
//D3D11RenderWindow.h
#include <d3d11.h>
class D3D11RenderWindow: public GfxRenderWindow
{
public:
bool initialize(HWND windowHandle);
private:
HWND windowHandle_; /// Win32 window handle
};
That is not so much the problem, this is a platform specific code that get included only by platform specific code. But we need to actually instanciate this type so an "entry point" need to know about the platform specific code too.
For example a factory class:
//GfxRenderWindowFactory.h
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
class GfxRenderWindow;
class GfxRenderWindowFactory
{
public:
static std::unique_ptr<GfxRenderWindow> make(HWND windowHandle);
};
Now this factory class need to be included by the "client" of the library (here a renderer). What I don't like is that #include "windows.h", because it is too error prone to me, anybody that include it, even if they don't need it will have all the world and windows.... Precompile header is not a solution because now it is enforced by the compiler that all cpp have include it (it is a valuable tool to speed compile time but not a tool to separate platform specific code from the portable code)
What I thought is to put the #include in the cpp before the include of its header instead of in the header file like this:
//GfxRenderWindowFactory.cpp
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include "GfxRenderWindowFactory.h"
/// Implementation of GfxRenderWindowFactory goed here ....
This way it force anybody that want to use this class to include the relevant platform specific header and they will be in better position to judge if they are including this header in a bad place like in one of their own header file.
What are your solution for this?
What do you think of my solution?, crazy?
I want to point out that to me it is of the uberimportance to do portable code right! Answer like just include windows.h and don't sweat about it is not a valid answer. It is not a good coding practice to me.
I hope i made my question clear. If not tell me i'll clarify
Thanks a lot!
## Edit ##
From a small conversation with hmjd I would like to keep the inclusion of windows.h in the header file since, i agree, this make it way more usable. So it would be nice to have a way to prevent the inclusion in a header file and this way enforce that the file can only be included in a cpp. Is this possible?
Is using a predefined macro, like WIN32, or a macro defined by your build system not sufficient:
#ifdef WIN32
#include <windows.h>
#else
include other platform specific headers
#endif
This is a common approach (and FWIW the only approach I have ever used).
Since the underlying issue is passing an HWND to GfxRenderWindowFactory::make, don't have GfxRenderWindowFactory::make take an HWND.
Hey I worked on the wxsmith cross-platform GUI API. The first thing that you need to do is create classes with your own handles. A handle is 1 of 3 things:
A void *.
Class *.
Struct *.
Use a function like so:
#define create_handle(handle) struct __##handle{unsigned int unused;}; typedef __##handle *##handle;
Then call this function and it creates a struct and a pointer to a struct. The pointer is the handle. Then cast to whatever you desire reinterpret_cast(your handle here); and your done then you can cast like this in your object files or your libs or dlls. And make a global define for your window handle, research how other OS's do it and you done.

Managing forward declarations

It's well known that using forward declarations is preferable to using #includes in header files, but what's the best way to manage forward declarations?
For a while, I was manually adding to each header file the forward declarations that were needed by that header file. However, I ended up with a bunch of header files repeating the same half-dozen or so forward declarations, which seems redundant, and maintaining these repeated lists got to be a bit tedious.
Forward declarations of typedefs (e.g., struct SensorRecordId; typedef std::vector<SensorRecordId> SensorRecordIdList;) is also a bit much to duplicate across multiple header files.
So then I made a ProjectForwards.h file that contains all of my forward declarations and included that wherever it was needed. At first, this seemed like a good idea - much less redundancy, and much easier maintenance of typedefs. But now, as a result of using ProjectForwards.h so heavily, whenever I add a new class to it, I have to rebuild the world, which slows development.
So what's the best way to manage forward declarations? Should I bite the bullet and repeat individual forward declarations across multiple subsystems? Continue with the ProjectForwards.h approach? Try to split ProjectForwards.h into several SubsystemForwards.h files? Some other solution I'm overlooking?
It sounds like these classes are fairly common to much of your project. You might try some of these:
Do your best to break apart ProjectForwards.h into several files as you suggested. Make sure each subsystem only gets the declarations it truly needs. If nothing else, that process will force you to think about the coupling between your subsystems and you might find ways to reduce it. These are all good steps toward avoiding over-compilation.
Mimic <iosfwd>. Have each common class or module provide its own forward-include header that just provides the class names and any convenience typedefs. Then you can #include that everywhere. Yes, you'll repeat the list a lot, but think about it this way: nobody complains about #including <vector>, <string>, and <map> in six different places in their code.
Use Pimpl more often. This will have a similar effect to my previous suggestion but will require more work on your part. If your interfaces are stable, then you can safely provide the typedefs in those headers and #include them directly.
In general:
Have a forwards file for users of your module. This will only declare those classes that appear as part of the API.
If you have commonly used forwards in your implementation you can have an implementation-only based forwards file.
You probably don't need a forward declaration for every class you use.
I've never seen a "header of forward declares" that was actually useful (noone uses it), didn't quickly become stale (full of stuff that noone uses), and wasn't an iteration bottleneck (touched the forward declare header? recompile everything!). Generally they develop all three problems.
The core of your problem is system design. These subsystems you've mentioned should probably be including the header files that define the types they need to take as input or output. By breaking types that are being used by multiple subsystems into their own header file you'll strike a nice balance between isolation and efficient interop between subsystems.
Having done a lot of brown field maintenance I've never been fond of includes that do nothing but include other files or have forward declarations. I prefer to just have them in the header file. You can reduce the typing with the use of templates if your tools support them.
You could write a template that expands into your desired text. I would probably include something to make it stand out like
///Begin Forwarding
...
///End Forwarding
That would make it easy to grab and replace if you change the template. If you're more comfortable with tools like grep you could automate the updating from a command line. It would probably be simple to write a script that would update all files, or only the files passed in on the command line. Just a thought.
I don't think there is a single "best" solution, each has its own advantages and drawbacks. Even though it's more work, I personally favor the "each header file has its own forward declarations" approach, for the following reasons:
It's as lean as it can get: No additional files that need to be found and parsed.
No obfuscation: Just by looking at the header file you see exactly which types it needs.
No unnecessary namespace pollution. If you collect forward declarations in a ProjectForwards.h file, that file will contain the sum of all declarations needed by all of its consumers. So if only a single consumer needs a certain declaration, all the others will inherit it, too.
If these arguments are not convincing, maybe because they are too puristic :-), then I would suggest following the middle way of splitting ProjectForwards.h.
Here's what I generally do:
It's well known that using forward declarations is preferable to using #includes in header files, but what's the best way to manage forward declarations?
Library: Provide a dedicated client forward: (e.g. #include "MONThread/include.fwd.hpp"). Keep Libraries focused (small-ish), and make implementations private where possible.
Executable: Forward declare on demand, unless it comes from a library -- always use the library's forward include. Recognize what should be a library (logical or physical) -- many forwards suggest this, as patterns will emerge. Also try to isolate what can be hidden in the process. With libraries and executables, there should be some use of package private types -- these types do not belong in the client's forward headers.
So then I made a ProjectForwards.h file that contains all of my forward declarations and included that wherever it was needed. At first, this seemed like a good idea - much less redundancy, and much easier maintenance of typedefs. But now, as a result of using ProjectForwards.h so heavily, whenever I add a new class to it, I have to rebuild the world, which slows development.
Usually, that means too many large libraries are visible in high levels of the include graph. An ideal include graph (of a large system) is much wider than it is tall -- including what it needs with minimal excess. If every TU needs a few 100,000 lines, you're beyond a problem -- start removing large libraries from high levels.
If that really sounds unsatisfactory, analyze your program's dependencies.
Many people make the mistake (in larger projects) of including a ton of large libraries for convenience (e.g. in the pch), which results in recompiling the world (and the pch).
Evaluate your dependencies from time to time -- set some soft sensible limits for line count of preprocessor output.
The forward headers replace local forward declarations. They do not (generally) belong in the pch.
I personally only include in the global ProjectForwards.h the declarations that are truly global to all, or mostly all, the program. It could also include other files that are almost always needed, for example:
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
std::string get_installation_dir();
//...
That way this file rarely changes and there is not need to often rebuilds.
Also, if this file includes a bunch of standard headers, it would be a perfect candidate to be a pre-compiled header!
I was manually adding to each header file the forward declarations that were needed by that header file.
This is the only good way.
Also, if you have a typedef somewhere, it is better to somehow mask it. For example, instead of using a typedef like this :
typedef std::vector< MyClass > MyClassArray;
do this instead :
struct MyClassArray
{
std::vector< MyClass > t;
};
The bad thing is that you will not be able to use operators, so this will not always work. For example, if you have
typedef std::string MyString;
then it is better to go with typedef.
So then I made a ProjectForwards.h file that contains all of my forward declarations and included that wherever it was needed.
As you discovered, this is a very bad idea. Whenever you modify this header, you'll trigger the recompilation of all files that include it (directly or indirectly).
There is no escaping forward declaration where they are needed.
In your model, If each of your objects from one type communicate with other objects of another type using interfaces only then you will minimize the amount of forward declaration to interfaces only.
If you use templates then you can put your typedefs of them in the precompiled header file.

Ways not to write function headers twice?

I've got a C/C++ question, can I reuse functions across different object files or projects without writing the function headers twice? (one for defining the function and one for declaring it)
I don't know much about C/C++, Delphi and D. I assume that in Delphi or D, you would just write once what arguments a function takes and then you can use the function across diferent projects.
And in C you need the function declaration in header files *again??, right?. Is there a good tool that will create header files from C sources? I've got one, but it's not preprocessor-aware and not very strict. And I've had some macro technique that worked rather bad.
I'm looking for ways to program in C/C++ like described here http://www.digitalmars.com/d/1.0/pretod.html
Imho, generating the headers from the source is a bad idea and is unpractical.
Headers can contain more information that just function names and parameters.
Here are some examples:
a C++ header can define an abstract class for which a source file may be unneeded
A template can only be defined in a header file
Default parameters are only specified in the class definition (thus in the header file)
You usually write your header, then write the implementation in a corresponding source file.
I think doing the other way around is counter-intuitive and doesn't fit with the spirit of C or C++.
The only exception is can see to that is the static functions. A static function only appears in its source file (.cor .cpp) and can't (obviously) be used elsewhere.
While I agree it is often annoying to copy the header definition of a method/function to the source file, you can probably configure your code editor to ease this. I use Vim and a quick script helped me with this a lot. I guess a similar solution exists for most other editors.
Anyway, while this can seem annoying, keep in mind it also gives a greater flexibility. You can distribute your header files (.h, .hpp or whatever) and then transparently change the implementation in source files afterward.
Also, just to mention it, there is no such thing as C/C++: there is C and there is C++; those are different languages (which indeed share much, but still).
It seems to me that you don't really need/want to auto-generate headers from source; you want to be able to write a single file and have a tool that can intelligently split that into a header file and a source file.
Unfortunately, I'm not aware of any such tool. It's certainly possible to write one - but you'd need a given a C++ front end. You could try writing something using clang - but it would be a significant amount of work.
Considering you have declared some functions and wrote their implementation you will have a .c/cpp file and a header .h file.
What you must do in order to use those functions:
Create a library (DLL/so or static library .a/.lib - for now I recommend static library for the ease of use) from the files were the implementation resides
Use the header file (#include it) (you don't need to rewrite the header file again) in your programs to obtain the function definitions and link with your library from step 1.
Though >this< is an example for Visual Studio it makes perfect sense for other development environments also.
This seems like a rudimentary question, so assuming I have not mis-read,
Here is a basic example of re-use, to answer your first question:
#include "stdio.h"
int main( int c, char ** argv ){
puts( "Hello world" );
}
Explanation:
1. stdio.h is a C header file containing (among others) the definition of a function called puts().
2. in main, puts() is called, from the included definition.
Some compilers (including gcc I think ) have an option to generate headers.
There is always very much confusion about headers and source-files in C++. The links I provided should help to clear that up a little.
If you are in the situation that you want to extract headers from source-file, then you probably went about it the wrong way. Usually you first declare your function in a header-file, and then provide an implementation (definition) for it in a source-file. If your function is actually a method of a class, you can also provide the definition in header file.
Technically, a header file is just a bunch of text that is actually inserted into the source file by the preprocessor:
#include <vector>
tells the preprocessor to insert contents of the file vector at the exact place where the #include appears. This really just text-replacement. So, header-files are not some kind of special language construct. They contain normal code. But by putting that code into a separate file, you can easily include it in other files using the preprocessor.
I think it's a good question which is what led me to ask this: Visual studio: automatically update C++ cpp/header file when the other is changed?
There are some refactoring tools mentioned but unfortunately I don't think there's a perfect solution; you simply have to write your function signatures twice. The exception is when you are writing your implementations inline, but there are reasons why you can't or shouldn't always do this.
You might be interested in Lazy C++. However, you should do a few projects the old-fashioned way (with separate header and source files) before attempting to use this tool. I considered using it myself, but then figured I would always be accidentally editing the generated files instead of the lzz file.
You could just put all the definitions in the header file...
This goes against common practice, but is not unheard of.

Is it a good practice to place C++ definitions in header files?

My personal style with C++ has always to put class declarations in an include file, and definitions in a .cpp file, very much like stipulated in Loki's answer to C++ Header Files, Code Separation. Admittedly, part of the reason I like this style probably has to do with all the years I spent coding Modula-2 and Ada, both of which have a similar scheme with specification files and body files.
I have a coworker, much more knowledgeable in C++ than I, who is insisting that all C++ declarations should, where possible, include the definitions right there in the header file. He's not saying this is a valid alternate style, or even a slightly better style, but rather this is the new universally-accepted style that everyone is now using for C++.
I'm not as limber as I used to be, so I'm not really anxious to scrabble up onto this bandwagon of his until I see a few more people up there with him. So how common is this idiom really?
Just to give some structure to the answers: Is it now The Way™, very common, somewhat common, uncommon, or bug-out crazy?
Your coworker is wrong, the common way is and always has been to put code in .cpp files (or whatever extension you like) and declarations in headers.
There is occasionally some merit to putting code in the header, this can allow more clever inlining by the compiler. But at the same time, it can destroy your compile times since all code has to be processed every time it is included by the compiler.
Finally, it is often annoying to have circular object relationships (sometimes desired) when all the code is the headers.
Bottom line, you were right, he is wrong.
EDIT: I have been thinking about your question. There is one case where what he says is true. templates. Many newer "modern" libraries such as boost make heavy use of templates and often are "header only." However, this should only be done when dealing with templates as it is the only way to do it when dealing with them.
EDIT: Some people would like a little more clarification, here's some thoughts on the downsides to writing "header only" code:
If you search around, you will see quite a lot of people trying to find a way to reduce compile times when dealing with boost. For example: How to reduce compilation times with Boost Asio, which is seeing a 14s compile of a single 1K file with boost included. 14s may not seem to be "exploding", but it is certainly a lot longer than typical and can add up quite quickly when dealing with a large project. Header only libraries do affect compile times in a quite measurable way. We just tolerate it because boost is so useful.
Additionally, there are many things which cannot be done in headers only (even boost has libraries you need to link to for certain parts such as threads, filesystem, etc). A Primary example is that you cannot have simple global objects in header only libs (unless you resort to the abomination that is a singleton) as you will run into multiple definition errors. NOTE: C++17's inline variables will make this particular example doable in the future.
As a final point, when using boost as an example of header only code, a huge detail often gets missed.
Boost is library, not user level code. so it doesn't change that often. In user code, if you put everything in headers, every little change will cause you to have to recompile the entire project. That's a monumental waste of time (and is not the case for libraries that don't change from compile to compile). When you split things between header/source and better yet, use forward declarations to reduce includes, you can save hours of recompiling when added up across a day.
The day C++ coders agree on The Way, lambs will lie down with lions, Palestinians will embrace Israelis, and cats and dogs will be allowed to marry.
The separation between .h and .cpp files is mostly arbitrary at this point, a vestige of compiler optimizations long past. To my eye, declarations belong in the header and definitions belong in the implementation file. But, that's just habit, not religion.
Code in headers is generally a bad idea since it forces recompilation of all files that includes the header when you change the actual code rather than the declarations. It will also slow down compilation since you'll need to parse the code in every file that includes the header.
A reason to have code in header files is that it's generally needed for the keyword inline to work properly and when using templates that's being instanced in other cpp files.
What might be informing you coworker is a notion that most C++ code should be templated to allow for maximum usability. And if it's templated, then everything will need to be in a header file, so that client code can see it and instantiate it. If it's good enough for Boost and the STL, it's good enough for us.
I don't agree with this point of view, but it may be where it's coming from.
I think your co-worker is smart and you are also correct.
The useful things I found that putting everything into the headers is that:
No need for writing & sync headers and sources.
The structure is plain and no circular dependencies force the coder to make a "better" structure.
Portable, easy to embedded to a new project.
I do agree with the compiling time problem, but I think we should notice that:
The change of source file are very likely to change the header files which leads to the whole project be recompiled again.
Compiling speed is much faster than before. And if you have a project to be built with a long time and high frequency, it may indicates that your project design has flaws. Seperate the tasks into different projects and module can avoid this problem.
Lastly I just wanna support your co-worker, just in my personal view.
Often I'll put trivial member functions into the header file, to allow them to be inlined. But to put the entire body of code there, just to be consistent with templates? That's plain nuts.
Remember: A foolish consistency is the hobgoblin of little minds.
As Tuomas said, your header should be minimal. To be complete I will expand a bit.
I personally use 4 types of files in my C++ projects:
Public:
Forwarding header: in case of templates etc, this file get the forwarding declarations that will appear in the header.
Header: this file includes the forwarding header, if any, and declare everything that I wish to be public (and defines the classes...)
Private:
Private header: this file is a header reserved for implementation, it includes the header and declares the helper functions / structures (for Pimpl for example or predicates). Skip if unnecessary.
Source file: it includes the private header (or header if no private header) and defines everything (non-template...)
Furthermore, I couple this with another rule: Do not define what you can forward declare. Though of course I am reasonable there (using Pimpl everywhere is quite a hassle).
It means that I prefer a forward declaration over an #include directive in my headers whenever I can get away with them.
Finally, I also use a visibility rule: I limit the scopes of my symbols as much as possible so that they do not pollute the outer scopes.
Putting it altogether:
// example_fwd.hpp
// Here necessary to forward declare the template class,
// you don't want people to declare them in case you wish to add
// another template symbol (with a default) later on
class MyClass;
template <class T> class MyClassT;
// example.hpp
#include "project/example_fwd.hpp"
// Those can't really be skipped
#include <string>
#include <vector>
#include "project/pimpl.hpp"
// Those can be forward declared easily
#include "project/foo_fwd.hpp"
namespace project { class Bar; }
namespace project
{
class MyClass
{
public:
struct Color // Limiting scope of enum
{
enum type { Red, Orange, Green };
};
typedef Color::type Color_t;
public:
MyClass(); // because of pimpl, I need to define the constructor
private:
struct Impl;
pimpl<Impl> mImpl; // I won't describe pimpl here :p
};
template <class T> class MyClassT: public MyClass {};
} // namespace project
// example_impl.hpp (not visible to clients)
#include "project/example.hpp"
#include "project/bar.hpp"
template <class T> void check(MyClass<T> const& c) { }
// example.cpp
#include "example_impl.hpp"
// MyClass definition
The lifesaver here is that most of the times the forward header is useless: only necessary in case of typedef or template and so is the implementation header ;)
To add more fun you can add .ipp files which contain the template implementation (that is being included in .hpp), while .hpp contains the interface.
As apart from templatized code (depending on the project this can be majority or minority of files) there is normal code and here it is better to separate the declarations and definitions. Provide also forward-declarations where needed - this may have effect on the compilation time.
Generally, when writing a new class, I will put all the code in the class, so I don't have to look in another file for it.. After everything is working, I break the body of the methods out into the cpp file, leaving the prototypes in the hpp file.
I personally do this in my header files:
// class-declaration
// inline-method-declarations
I don't like mixing the code for the methods in with the class as I find it a pain to look things up quickly.
I would not put ALL of the methods in the header file. The compiler will (normally) not be able to inline virtual methods and will (likely) only inline small methods without loops (totally depends on the compiler).
Doing the methods in the class is valid... but from a readablilty point of view I don't like it. Putting the methods in the header does mean that, when possible, they will get inlined.
I think that it's absolutely absurd to put ALL of your function definitions into the header file. Why? Because the header file is used as the PUBLIC interface to your class. It's the outside of the "black box".
When you need to look at a class to reference how to use it, you should look at the header file. The header file should give a list of what it can do (commented to describe the details of how to use each function), and it should include a list of the member variables. It SHOULD NOT include HOW each individual function is implemented, because that's a boat load of unnecessary information and only clutters the header file.
If this new way is really The Way, we might have been running into different direction in our projects.
Because we try to avoid all unnecessary things in headers. That includes avoiding header cascade. Code in headers will propably need some other header to be included, which will need another header and so on. If we are forced to use templates, we try avoid littering headers with template stuff too much.
Also we use "opaque pointer"-pattern when applicable.
With these practices we can do faster builds than most of our peers. And yes... changing code or class members will not cause huge rebuilds.
I put all the implementation out of the class definition. I want to have the doxygen comments out of the class definition.
IMHO, He has merit ONLY if he's doing templates and/or metaprogramming. There's plenty of reasons already mentioned that you limit header files to just declarations. They're just that... headers. If you want to include code, you compile it as a library and link it up.
Doesn't that really depends on the complexity of the system, and the in-house conventions?
At the moment I am working on a neural network simulator that is incredibly complex, and the accepted style that I am expected to use is:
Class definitions in classname.h
Class code in classnameCode.h
executable code in classname.cpp
This splits up the user-built simulations from the developer-built base classes, and works best in the situation.
However, I'd be surprised to see people do this in, say, a graphics application, or any other application that's purpose is not to provide users with a code base.
Template code should be in headers only. Apart from that all definitions except inlines should be in .cpp. The best argument for this would be the std library implementations which follow the same rule. You would not disagree the std lib developers would be right regarding this.
I think your co-worker is right as long as he does not enter in the process to write executable code in the header.
The right balance, I think, is to follow the path indicated by GNAT Ada where the .ads file gives a perfectly adequate interface definition of the package for its users and for its childs.
By the way Ted, have you had a look on this forum to the recent question on the Ada binding to the CLIPS library you wrote several years ago and which is no more available (relevant Web pages are now closed). Even if made to an old Clips version, this binding could be a good start example for somebody willing to use the CLIPS inference engine within an Ada 2012 program.