C++ One Header Multiple Sources - c++

I have a large class Foo1:
class Foo {
public:
void apples1();
void apples2();
void apples3();
void oranges1();
void oranges2();
void oranges3();
}
Splitting the class is not an option2, but the foo.cpp file has grown rather large. Are there any major design flaws to keeping the definition of the class in foo.h and splitting the implementation of the functions into foo_apples.cpp and foo_oranges.cpp.
The goal here is purely readability and organization for myself and other developers working on the system that includes this class.
1"Large" means some 4000 lines, not machine-generated.
2Why? Well, apples and oranges are actually categories of algorithms that operate on graphs but use each other quite extensively. They can be separated but due to the research nature of the work, I'm constantly rewiring the way each algorithm works which I found for me does not (in the early stage) jive well with the classic OOP principles.

Are there any major design flaws to keeping the definition of the class in foo.h and splitting the implementation of the functions into foo_apples.cpp and foo_oranges.cpp.
to pick nits: Are there any major design flaws to keeping the declaration of the class in foo.h and splitting the definitions of the methods into foo_apples.cpp and foo_oranges.cpp.
1) apples and oranges may use the same private programs. an example of this would be implementation found in an anonymous namespace.
in that case, one requirement would be to ensure your static data is not multiply defined. inline functions are not really a problem if they do not use static data (although their definitions may be multiply exported).
to overcome those problems, you may then be inclined to utilise storage in the class -- which could introduce dependencies by increasing of data/types which would have otherwise been hidden. in either event, it can increase complexity or force you to write your program differently.
2) it increases complexity of static initialization.
3) it increases compile times
the alternative i use (which btw many devs detest) in really large programs is to create a collection of exported local headers. these headers are visible only to the package/library. in your example, it can be illustrated by creating the following headers: Foo.static.exported.hpp (if needed) + Foo.private.exported.hpp (if needed) + Foo.apples.exported.hpp + Foo.oranges.exported.hpp.
then you would write Foo.cpp like so:
#include "DEPENDENCIES.hpp"
#include "Foo.static.exported.hpp" /* if needed */
#include "Foo.private.exported.hpp" /* if needed */
#include "Foo.apples.exported.hpp"
#include "Foo.oranges.exported.hpp"
/* no definitions here */
you can easily adjust how those files are divided based on your needs. if you write your programs using c++ conventions, there are rarely collisions across huge TUs. if you write like a C programmer (lots of globals, preprocessor abuse, low warning levels and free declarations), then this approach will expose a lot of issues you probably won't care to correct.

From a technical standpoint, there is no penalty to doing this at all, but I have never seen it done in practice. This is simply a issue of style, and in that spirit, if it helps you to better read the class, then you would be doing yourself a disservice by not using multiple source files.
edit: Adding to that though, are you physically scrolling through your source, like, with your middle mouse wheel? As someone else already mentioned, IDE's almost universally let you right click on a function declaration, and go to the definition. And even if that's not the case for your IDE, and you use notepad or something, it will at least have ctrl+f. I would be lost without find and replace.

Yes, you can define the class in one header file and split the function implementations accross multiple source files. It is not usually the common practice but yes it will work and there will be no overheads.
If the aim to do so, is just plain readability, then perhaps it is not a good idea to do so, because it is not so common practice to have class function definitions accross multipls source files and might just confuse someone.

Actually i don't see any reasons to split implementation because other developers should work with the interface, but not the implementation.
Also any normal IDE provide an easy ability to jump from function declaration to it's defenition. So there is no reason to search the function implementations manually.

Related

Inline functions in header files in C++

Why is it a bad practice to define the functions of the class in the header files?
Lets say I have a header file and I define the functions of the class in the class definition itself like,
headerfile.hpp
#ifndef _HEADER_FILE_
#define _HEADER_FILE_
class node{
int i;
public:
int nextn(){
......
return i;
}
}
#endif //_HEADER_FILE_
So defining the function in the class like this makes the function "Inline".So if we include this header file in say two .cpp files, will it cause "Multiple definition error" ??Is it a bad practice to define the functions like this in the class definition?
It is a bad practice for the following reasons: If you need to change the code, let's say to add a trace in a simple setter (they are commonly in the .h); then you will need to recompile all CPP files that #includes the change (and any dependency of). In my current project that could reach up to 1 hour lost. If you later need to add another trace, then another and so on you quickly loose 1-2 days or work waiting for the compiler.
If you place your code in the CPP, then you only need to re-link, and that takes only a few minutes. Your project may be small today, but who knows in a few years. It's just a good habit to take.
Another (not so good) reason is that if you search your code base for the string "::MyFonction" you will not find it in the declaration since there is no "::" (we only want implementations). But a good IDE should find it anyway using a context search instead of a string search.
It's not bad practise (in fact it's commonplace) and it will not cause multiple definition errors. Inline functions never cause multiple definition errors, that's one of the meanings of inline.
The convention to separate prototypes (that is, the declaration of the class, its functions, their types) from implementation comes from both a design and a performance point of view.
Type checking and compiling your dependants is cheaper. Something that uses your class can be safely compiled without knowing your implementation.
Your compiler won't need to parse and recompile the same information lots of times each time you do compile those dependants.
The thing is to remember what it really means with you write #include at the top of a file in C++: it means "take all the contents of some other file, and put them here." So if you're using a class in lots of places all over your code base, then it's getting parsed every single time, and re-compiled in the context of that compilation unit.
This is precisely the reason why you have to put implementations of template classes in-line in the header file; the compiler needs to re-parse and compile the class for every different template instantiation (because that's what templates are about).
To answer your question directly:
* No, you will not get a multiple definition error.
* Maybe, some people would consider it back practice from a design points of view (others wouldn't)
* You might see a difference in performance (though not necessarily a degredation, as I believe - though I could be wrong), that despite the above, it can still be faster to compile header-only libraries.
Probably avoid doing this if your implementations are long, the class is used often in the codebase, and will be subject to frequent change.
For further reading, it might be worth checking up on "precompiled headers."
It is legal to define (inline) functions in your hpp file. Note that some people prefer to gather then under a dedicated extension like "inl.hpp", but this is just a style preference.

A "source-less" C++ idiom

I am developing a fairly large C++ support library, and have found myself moving towards a header-only approach. In C++ this almost works because you can implement where you define in classes. For templated methods, the implementation has to be in the same file anyway, so I find that it is much easier to just keep the implementation with the definition.
However, there are several times where "sources" must be used. As just one example, circular dependencies sometimes occur and the implementation has to be written outside the class definition. Here is how I am handling it:
//part of libfoo.h
class Bar
{
void CircularDependency(void);
};
#ifdef LIBFOO_COMPILE_INLINE
void Bar::CircularDependency(void)
{
//...
}
#endif
Then the project that uses libfoo would do the following in main.cpp:
//main.cpp
#define LIBFOO_COMPILE_INLINE
#include "libfoo.h"
And in any other .cpp:
//other.cpp
#include "libfoo.h"
The point is that the compile-inline section only gets compiled once (in main.cpp).
And finally my question: is there a name for this idiom or any other projects that work this way? It just seems to be a natural outcome of the implementation and definition being blurred by templating and class methods. And: are there any reasons why this is a bad idea or why it would potentially not scale well?
Quick aside: I know that many coders, with good reason, prefer their headers to resemble interfaces and not implementations, but IMHO documentation generators are better suited to describing interfaces because I like to hide private members all together :-)
You should be able to use the inline keyword if the circular dependency problem is resolved by the time the definition of Bar::CircularDependency() would show up in the libfoo.h header:
//part of libfoo.h
class Bar
{
void CircularDependency(void);
};
// other stuff that 'resolves' the circular dependency
// ...
// ...
inline void Bar::CircularDependency(void)
{
//...
}
That would make your library easier to use (the user wouldn't need to deal with the fact that LIBFOO_COMPILE_INLINE needed to be defined in exactly one place where the header is included).
Circular dependencies are not really a problem as you can forward decalre that functions are inline. I wouldn't really suggest this, though: while the "source-less" approach initially makes it easier to use a library coming from somewhere, it causes longer compile times and tighter coupling between files. In a huge source base this is essentially killing the hOpe to get code build in reasonable times. Sure huge only starts at a couple millions lines of code but who cares about trivial programs...? (and, yes, the place I work at has several tens of millions lines of code being build into single executables)
My reasons for why this is a bad idea.
Increase in compile time
Every individual compilation unit that includes the header should compile all the header files in addition to the source in itself. This would probably increase the compile time and might be frustrating while testing your code, with small changes. One could argue the compiler might optimize it, but IMO it could not optimize it beyond a point.
Bigger code segment
If all the functions are written inline, it means that the compiler has to put all that code wherever the function is called. This is going to blow up the code segment and it would affect the load time of the program and the program would take more memory.
Creates dependency in client code with tight coupling
Whenever you change your implementation, every client should get updated (by re compiling the code). But if the implementation has been put in an independent shared object (.so or .dll), the client should just link to the new shared object.
Also I am not sure why one would do this.
//main.cpp
#define LIBFOO_COMPILE_INLINE
#include "libfoo.h"
If at all one has to do this, (s)he could have simply put the implementation code in main.cpp itself. Anyway, you could define LIBFOO_COMPILE_INLINE only in one compilation unit. Otherwise you will duplicate definitions.
I am actually much interested in developing a idiom to write cohesive template code. Sometime in future, C++ compiler should support writing cohesive templates. By this, I mean the client need not have to recompile the code, whenever template implementation in modified.

Why is including a header file such an evil thing?

I have seen many explanations on when to use forward declarations over including header files, but few of them go into why it is important to do so. Some of the reasons I have seen include the following:
compilation speed
reducing complexity of header file management
removing cyclic dependencies
Coming from a .net background I find header management frustrating. I have this feeling I need to master forward declarations, but I have been scrapping by on includes so far.
Why cannot the compiler work for me and figure out my dependencies using one mechanism (includes)?
How do forward declarations speed up compilations since at some point the object referenced will need to be compiled?
I can buy the argument for reduced complexity, but what would a practical example of this be?
"to master forward declarations" is not a requirement, it's a useful guideline where possible.
When a header is included, and it pulls in more headers, and yet more, the compiler has to do a lot of work processing a single translation module.
You can see how much, for example, with gcc -E:
A single #include <iostream> gives my g++ 4.5.2 additional 18,560 lines of code to process.
A #include <boost/asio.hpp> adds another 74,906 lines.
A #include <boost/spirit/include/qi.hpp> adds 154,024 lines, that's over 5 MB of code.
This adds up, especially if carelessly included in some file that's included in every file of your project.
Sometimes going over old code and pruning unnecessary includes improves the compilation dramatically just because of that. Replacing includes with forward declarations in the translation modules where only references or pointers to some class are used, improves this even further.
Why cannot the compiler work for me and figure out my dependencies using one mechanism (includes)?
It cannot because, unlike some other languages, C++ has an ambiguous grammar:
int f(X);
Is it a function declaration or a variable definition? To answer this question the compiler must know what does X mean, so X must be declared before that line.
Because when you're doing something like this :
bar.h :
class Bar {
int foo(Foo &);
}
Then the compiler does not need to know how the Foo struct / class is defined ; so importing the header that defines Foo is useless. Moreover, importing the header that defines Foo might also need importing the header that defines some other class that Foo uses ; and this might mean importing the header that defines some other class, etc.... turtles all the way.
In the end, the file that the compiler is working against is almost like the result of copy pasting all the headers ; so it will get big for no good reason, and when someone makes a typo in a header file that you don't need (or import , or something like that), then compiling your class starts to take waaay too much time (or fail for no obvious reason).
So it's a good thing to give as little info as needed to the compiler.
How do forward declarations speed up compilations since at some point the object referenced will need to be compiled?
1) reduced disk i/o (fewer files to open, fewer times)
2) reduced memory/cpu usage
most translations need only a name. if you use/allocate the object, you'll need its declaration.
this is probably where it will click for you: each file you compile compiles what is visible in its translation.
a poorly maintained system will end up including a ton of stuff it does not need - then this gets compiled for every file it sees. by using forwards where possible, you can bypass that, and significantly reduce the number of times a public interface (and all of its included dependencies) must be compiled.
that is to say: the content of the header won't be compiled once. it will be compiled over and over. everything in this translation must be parsed, checked that it's a valid program, checked for warnings, optimized, etc. many, many times.
including lazily only adds significant disk/cpu/memory increase, which turns into intolerable build times for you, while introducing significant dependencies (in non-trivial projects).
I can buy the argument for reduced complexity, but what would a practical example of this be?
unnecessary includes introduce dependencies as side effects. when you edit an include (necessary or not), then every file which includes it must be recompiled (not trivial when hundreds of thousands of files must be unnecessarily opened and compiled).
Lakos wrote a good book which covers this in detail:
http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620/ref=sr_1_1?ie=UTF8&s=books&qid=1304529571&sr=8-1
Header file inclusion rules specified in this article will help reduce the effort in managing header files.
I used forward declarations simply to reduce the amount of navigation between source files done. e.g. if module X calls some glue or interface function F in module Y, then using a forward declaration means the writing the function and the call can be done by only visiting 2 places, X.c and Y.c not so much of an issue when a good IDE helps you navigate, but I tend to prefer coding bottom-up creating working code then figuring out how to wrap it rather than through top down interface specification.. as the interfaces themselves evolve it's handy to not have to write them out in full.
In C (or c++ minus classes) it's possible to truly keep structure details Private by only defining them in the source files that use them, and only exposing forward declarations to the outside world - a level of black boxing that requires performance-destroying virtuals in the c++/classes way of doing things. It's also possible to avoid needing to prototype things (visiting the header) by listing 'bottom-up' within the source files (good old static keyword).
The pain of managing headers can sometimes expose how modular your program is or isn't - if its' truly modular, the number of headers you have to visit and the amount of code & datastructures declared within them should be minimized.
Working on a big project with 'everything included everywhere' through precompiled headers won't encourage this real modularity.
module dependancies can correlate with data-flow relating to performance issues, i.e. both i-cache & d-cache issues. If a program involves many modules that call each other & modify data at many random places, it's likely to have poor cache-coherency - the process of optimizing such a program will often involve breaking up passes and adding intermediate data.. often playing havoc with many'class diagrams'/'frameworks' (or at least requiring the creation of many intermediates datastructures). Heavy template use often means complex pointer-chasing cache-destroying data structures. In its optimized state, dependancies & pointer chasing will be reduced.
I believe forward declarations speed up compilation because the header file is ONLY included where it is actually used. This reduces the need to open and close the file once. You are correct that at some point the object referenced will need to be compiled, but if I am only using a pointer to that object in my other .h file, why actually include it? If I tell the compiler I am using a pointer to a class, that's all it needs (as long as I am not calling any methods on that class.)
This is not the end of it. Those .h files include other .h files... So, for a large project, opening, reading, and closing, all the .h files which are included repetitively can become a significant overhead. Even with #IF checks, you still have to open and close them a lot.
We practice this at my source of employment. My boss explained this in a similar way, but I'm sure his explanation was more clear.
How do forward declarations speed up compilations since at some point the object referenced will need to be compiled?
Because include is a preprocessor thing, which means it is done via brute force when parsing the file. Your object will be compiled once (compiler) then linked (linker) as appropriate later.
In C/C++, when you compile, you've got to remember there is a whole chain of tools involved (preprocessor, compiler, linker plus build management tools like make or Visual Studio, etc...)
Good and evil. The battle continues, but now on the battle field of header files. Header files are a necessity and a feature of the language, but they can create a lot of unnecessary overhead if used in a non optimal way, e.g. not using forward declarations etc.
How do forward declarations speed up
compilations since at some point the
object referenced will need to be
compiled?
I can buy the argument for reduced
complexity, but what would a practical
example of this be?
Forward declarations are bad ass. My experience is that a lot of c++ programmers are not aware of the fact that you don't have to include any header file, unless you actually want to use some type, e.g. you need to have the type defined so the compiler understands what you want to do. It's important to try and refrain from including header files in other header files.
Just passing around a pointer from one function to another, only requires a forward declaration:
// someFile.h
class CSomeClass;
void SomeFunctionUsingSomeClass(CSomeClass* foo);
Including someFile.h does not require you to include the header file of CSomeClass, since you are merely passing a pointer to it, not using the class. This means that the compiler only needs to parse one line (class CSomeClass;) instead of an entire header file (that might be chained to other header files etc etc).
This reduces both compile time and link time, and we are talking big optimizations here if you have many headers and many classes.

C++ Function Conventions?

Just had a 'Fundamentals of Programming' lecture at uni and was told that the convention for using/declaring functions is to have the main() function at the top of the program, with functions/procedures below it and to use forward declarations to prevent compiler errors.
However, I've always done it the other way - functions at top main() at bottom and not using forward declarations and don't think I've ever seen it otherwise.
Which is right? Or is it more a case of personal preference? Some clarification would be hugely appreciated.
It's up to you. Personally, I keep main on bottom because the times when I have other functions in there, it's either just one or two other little functions or a code snippet.
In real code, you'd have hopefully split your project up (having multiple "unrelated" functions in a file is bad) and so main would likely be nearly alone in the file. You'd just #include the things main needs to get things going and use them.
There could be the case when your functions are related to each other. If you simply write them above the main() without forward-declaration you have to order them so they'll know the functions they depend on. In some cases (circular references) it won't even be possible to compile without forward declaration.
When forward declaring the functions you won't run into this issue.
Additionally when having main() as first function, you'll produce more readable code, but thats perhaps just personal preference.
It could also be more readable cause another coder has on overview about the functions he'll find in the file.
If there is a standard, it's to have the function declarations in a .h file which is included. That way, it doesn't matter what the order of functions in the file is. I almost never write functions without a declaration, and it takes me aback when other people do.
The standard most professional C++ developers use is this.
two files per class: the header file (named e.g., Class.h), which only declares all of the class' data members and functions; and the implementation file (named Class.cpp in the same example), containing only implementations of those functions.
the main function (if your solution has it) goes into a file named, e.g. Main.cpp all by itself.
It is OK to put multiple classes or even the entire program into one file when you work on small-scale home or school projects. Because of the small scale, it doesn't really matter how you order the classes or the functions. You can do what is more convenient to you. But if your professor requires students to follow certain code standards for homework (e.g. put main() first), then you have to follow those standards.
This approach is most likely favoured by your professor and most likely the reason she's teaching it as convention. There are two options here, go with the flow (i.e. don't try to disrupt and potentially get marked down for stuff because your professor feels that you're not following "convention") or explain to her - there is no requirement to do it this way (or any other way), as long as the intention of the code is clear!
The advice to have declarations (function prototypes) is more related to C then to C++, because in C++ there are no implicit function declarations, so you must always declare before use. Therefore you will definitely have at least one function declaration which is not definition if you have a recursion involving more then one function.
For a small project use whatever style you want but be consistent.
For a large project you'll probably need several .cpp files and have the interfaces (be they classes or functions) defined in the header files. Also be consistent at least within a single file.
And the last thing, have I said to be consistent?
I normally use the second form because you have to maintain function declarations - they must have the right signature and name, and imo, they're just excessive typing when you could just define the functions first. No maintenance, no wasted time.
I think the principle that applies here is "Don't Repeat Yourself". If you use a forward declaration, you're repeating yourself unnecessarily.

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.