Thinking Time - Why do you want to split your file anyway?
As the title suggests, the end problem I have is multiple definition linker errors. I have actually fixed the problem, but I haven't fixed the problem in the correct way. Before starting I want to discuss the reasons for splitting a class file into multiple files. I have tried to put all the possible scenarios here - if I missed any, please remind me and I can make changes. Hopefully the following are correct:
Reason 1 To save space:
You have a file containing the declaration of a class with all class members. You place #include guards around this file (or #pragma once) to ensure no conflicts arise if you #include the file in two different header files which are then included in a source file. You compile a separate source file with the implementation of any methods declared in this class, as it offloads many lines of code from your source file, which cleans things up a bit and introduces some order to your program.
Example: As you can see, the below example could be improved by splitting the implementation of the class methods into a different file. (A .cpp file)
// my_class.hpp
#pragma once
class my_class
{
public:
void my_function()
{
// LOTS OF CODE
// CONFUSING TO DEBUG
// LOTS OF CODE
// DISORGANIZED AND DISTRACTING
// LOTS OF CODE
// LOOKS HORRIBLE
// LOTS OF CODE
// VERY MESSY
// LOTS OF CODE
}
// MANY OTHER METHODS
// MEANS VERY LARGE FILE WITH LOTS OF LINES OF CODE
}
Reason 2 To prevent multiple definition linker errors:
Perhaps this is the main reason why you would split implementation from declaration. In the above example, you could move the method body to outside the class. This would make it look much cleaner and structured. However, according to this question, the above example has implicit inline specifiers. Moving the implementation from within the class to outside the class, as in the example below, will cause you linker errors, and so you would either inline everything, or move the function definitions to a .cpp file.
Example: _The example below will cause "multiple definition linker errors" if you do not move the function definition to a .cpp file or specify the function as inline.
// my_class.hpp
void my_class::my_function()
{
// ERROR! MULTIPLE DEFINITION OF my_class::my_function
// This error only occurs if you #include the file containing this code
// in two or more separate source (compiled, .cpp) files.
}
To fix the problem:
//my_class.cpp
void my_class::my_function()
{
// Now in a .cpp file, so no multiple definition error
}
Or:
// my_class.hpp
inline void my_class::my_function()
{
// Specified function as inline, so okay - note: back in header file!
// The very first example has an implicit `inline` specifier
}
Reason 3 You want to save space, again, but this time you are working with a template class:
If we are working with template classes, then we cannot move the implementation to a source file (.cpp file). That's not currently allowed by (I assume) either the standard or by current compilers. Unlike the first example of Reason 2, above, we are allowed to place the implementation in the header file. According to this question the reason is that template class methods also have implied inline specifiers. Is that correct? (It seems to make sense.) But nobody seemed to know on the question I have just referenced!
So, are the two examples below identical?
// some_header_file.hpp
#pragma once
// template class declaration goes here
class some_class
{
// Some code
};
// Example 1: NO INLINE SPECIFIER
template<typename T>
void some_class::class_method()
{
// Some code
}
// Example 2: INLINE specifier used
template<typename T>
inline void some_class::class_method()
{
// Some code
}
If you have a template class header file, which is becoming huge due to all the functions you have, then I believe you are allowed to move the function definitions to another header file (usually a .tpp file?) and then #include file.tpp at the end of your header file containing the class declaration. You must NOT include this file anywhere else, however, hence the .tpp rather than .hpp.
I assume you could also do this with the inline methods of a regular class? Is that allowed also?
Question Time
So I have made some statements above, most of which relate to the structuring of source files. I think everything I said was correct, because I did some basic research and "found out some stuff", but this is a question and so I don't know for sure.
What this boils down to, is how you would organize code within files. I think I have figured out a structure which will always work.
Here is what I have come up with. (This is my class code file organization/structure standard, if you like. Don't know if it will be very useful yet, that's the point of asking.)
1: Declare the class (template or otherwise) in a .hpp file, including all methods, friend functions and data.
2: At the bottom of the .hpp file, #include a .tpp file containing the implementation of any inline methods. Create the .tpp file and ensure all methods are specified to be inline.
3: All other members (non-inline functions, friend functions and static data) should be defined in a .cpp file, which #includes the .hpp file at the top to prevent errors like "class ABC has not been declared". Since everything in this file will have external linkage, the program will link correctly.
Do standards like this exist in industry? Will the standard I came up with work in all cases?
Your three points sound about right. That's the standard way to do things (although I've not seen .tpp extension before, usually it's .inl), although personally I just put inline functions at the bottom of header files rather than in a separate file.
Here is how I arrange my files. I omit the forward declare file for simple classes.
myclass-fwd.h
#pragma once
namespace NS
{
class MyClass;
}
myclass.h
#pragma once
#include "headers-needed-by-header"
#include "myclass-fwd.h"
namespace NS
{
class MyClass
{
..
};
}
myclass.cpp
#include "headers-needed-by-source"
#include "myclass.h"
namespace
{
void LocalFunc();
}
NS::MyClass::...
Replace pragma with header guards according to preference..
The reason for this approach is to reduce header dependencies, which slow down compile times in large projects. If you didn't know, you can forward declare a class to use as a pointer or reference. The full declaration is only needed when you construct, create or use members of the class.
This means another class which uses the class (takes parameters by pointer/reference) only has to include the fwd header in its own header. The full header is then included in the second class's source file. This greatly reduces the amount of unneeded rubbish you get when pulling in a big header, which pulls in another big header, which pulls in another...
The next tip is the unnamed namespace (sometimes called anonymous namespace). This can only appear in a source file and it is like a hidden namespace only visible to that file. You can place local functions, classes etc here which are only used by the the source file. This prevents name clashes if you create something with the same name in two different files. (Two local function F for example, may give linker errors).
The main reason to separate interface from implementation is so that you don't have to recompile all of your code when something in the implementation changes; you only have to recompile the source files that changed.
As for "Declare the class (template or otherwise)", a template is not a class. A template is a pattern for creating classes. More important, though, you define a class or a template in a header. The class definition includes declarations of its member functions, and non-inine member functions are defined in one or more source files. Inline member functions and all template functions should be defined in the header, by whatever combination of direct definitions and #include directives you prefer.
Do standards like this exist in industry?
Yes. Then again, coding standards that are rather different from the ones you expressed can also be found in industry. You are talking about coding standards, after all, and coding standards range from good to bad to ugly.
Will the standard I came up with work in all cases?
Absolutely not. For example,
template <typename T> class Foo {
public:
void some_method (T& arg);
...
};
Here, the definition of class template Foo doesn't know a thing about that template parameter T. What if, for some class template, the definitions of the methods vary depending on the template parameters? Your rule #2 just doesn't work here.
Another example: What if the corresponding source file is huge, a thousand lines long or longer? At times it makes sense to provide the implementation in multiple source files. Some standards go to the extreme of dictating one function per file (personal opinion: Yech!).
At the other extreme of a thousand-plus line long source file is a class that has no source files. The entire implementation is in the header. There's a lot to be said for header-only implementations. If nothing else, it simplifies, sometimes significantly, the linking problem.
Related
Currently, I am writing a few classes, all of which inherit from a base class and somehow enrich it. All of these classes use templates in order to take different elements as parameters (the classes are all variations of an abstract vector class). So I wrote all of the code in one big .hpp file because I read that splitting the code in .hpp and .cpp would cause linker problems (Splitting templated C++ classes into .hpp/.cpp files--is it possible?) and it wouldn't work.
So I was wondering, since it's not really clean and clear to have everything in a big .hpp file, should I split it and how would I do the splitting the right way in order to keep the code as intact as possible? Should I import the child classes into the base class? Do I have to forward declare all my classes in every .hpp file or not? How would the splitting interact with the templates.
If the code is necessary, I can add it. Just trying to keep it short if it isn't.
As far as splitting the code up, there is a technique for templated code where you can split up the declarations and definitions, at least visually (you'll see why I make that distinction in a moment). So you first start with the header, that will contain just your class and function declarations
Foo.h
template <typename T>
T some_foo(T x); // declaration
#include "Foo.inl"
Then you make a separate file for the implementation. Note that we #include this .inl file in our header, so as far as the compiler is concerned all of the code still exists in the header. Doing it this way is just for human readers, but this way you can split up the actual implementation code into separate files and just include them at the end of the header.
Foo.inl
<template <typename T>
T some_foo(T x) // definition
{
return x + 5;
}
Files:
header.hpp
something1.ipp
something2.ipp
something3.ipp
Content of header.hpp:
#ifndef COMPANY_PROJECT_HEADER_HPP
#define COMPANY_PROJECT_HEADER_HPP 1
#include "something1.ipp"
#include "something2.ipp"
#include "something3.ipp"
#endif
Easy peasy. #include is just a "copy-and-paste" operation so you can do what you like to arrange your files in a pleasing, and easy-to-maintain organisational structure.
All the files are headers, but I've given the "sub-headers" the extension .ipp to distinguish them.
So I wrote all of the code in one big .hpp file because I read that splitting the code in .hpp and .cpp would cause linker problems ... and it wouldn't work.
That only implies that you must not split the definition of the function templates from their declaration (or the definition of member function of a class template from the definition of the template). There is no reason to put the definition of all templates into a single header - which your post seems to imply that you did.
So I was wondering, since it's not really clean and clear to have everything in a big .hpp file, should I split it
Sure.
and how would I do the splitting the right way
Just be sure to keep the definitions of the templates in the same file that declared them - as described in the answers to the linked question. If you think that's messy, then you can put the definitions into another header and include that in the declaring header.
Do I have to forward declare all my classes in every .hpp file or not?
Only in headers that refer to the declarations, but don't need the complete definition.
I have what seems a relatively simple question, but one that keeps defying my efforts to understand it.
I apologise if it is a simple question, but like many simple questions, I can't seem to find a solid explanation anywhere.
With the below code:
/*foo.c*/
#include "bar.h"
int main() {
return(my_function(1,2));
}
/*bar.h*/
int my_function(int,int);
/*bar.c*/
#include "bar.h" /*is this necessary!?*/
int my_function(int x, int y) {
return(x+y);
}
Simply, is the second inclusion necessary? I don't understand why I keep seeing headers included in both source files. Surely if the function is declared in "foo.c" by including "bar.h," it does not need to be declared a second time in another linked source file (especially the one which actually defines it)??? A friend tried to explain to me that it didn't really matter for functions, but it did for structs, something which still eludes me! Help!
Is it simply for clarity, so that programmers can see which functions are being used externally?
I just don't get it!
Thanks!
In this particular case, it's unnecessary for the reason you described. It might be useful in situations where you have a more complex set of functions that might all depend on each other. If you include the header at the top of the .cpp file, you have effectively forward-declared every single function and so you don't have to worry about making sure your function definitions are in a certain order.
I also find that it clearly shows that these function definitions correspond to those declarations. This makes it easier for the reader to find how translation units depend on each other. Of course, the names of the files might be sufficient, but some more complex projects do not have one-to-one relationship between .cpp files and .h files. Sometimes headers are broken up into multiple parts, or many implementation files will have their external functions declared in a single header (common for large modules).
Really, all inclusions are unnecessary. You can always, after all, just duplicate the declarations (or definitions, in the case of classes) across all of the files that require them. We use the preprocessor to simplify this task and reduce the amount of redundant code. It's easier to stick to a pattern of always including the corresponding header because it will always work, rather than have to check each file every time you edit them and determine if the inclusion is necessary or not.
The way the C language (and C++) is designed is that the compiler processes each .c file in isolation.
You typically launch your compiler (cl.exe or gcc, for example) for one of your c files, and this produces one object file (.o or .obj).
Once all your object files have been generated, you run the linker, passing it all the object files, and it will tie them together into an executable.
That's why every .c file needs to include the headers it depends on. When the compiler is processing it, it knows nothing about which other .c files you may have. All it knows is the contents of the .c file you point it to, as well as the headers it includes.
In your simplified example inclusion of "bar.h" in "bar.c" is not necessary. But in real world in most cases it would be. If you have a class declaration in "bar.h", and "bar.c" has functions of this class, the inclusion is needed. If you have any other declaration which is used in "bar.c" - being it a constant, enum, etc. - again include is needed. Because in real world it is nearly always needed, the easy rule is - include the header file in the corresponding source file always.
If the header only declares global functions, and the source file only implements them (without calling any of them) then it's not strictly necessary. But that's not usually the case; in a large program, you rarely want global functions.
If the header defines a class, then you'll need to include it in the source file in order to define member functions:
void Thing::function(int x) {
//^^^^^^^ needs class definition
}
If the header declares functions in a namespace, then it's a good idea to put the definitions outside the namespace:
void ns::function(int x) {
//^^^^ needs previous declaration
}
This will give a nice compile-time error if the parameter types don't match a previous declaration - for which you'd need to include the header. Defining the function inside its namespace
namespace ns {
void function(int x) {
// ...
}
}
will silently declare a new overload if you get the parameter types wrong.
Simple rule is this(Considering foo is a member function of some class):-
So, if some header file is declaring a function say:=
//foo.h
void foo (int x);
Compiler would need to see this declaration anywhere you have defined this function ( to make sure your definition is in line with declaration) and you are calling this function ( to make sure you have called the function with correct number and type of arguments).
That means you have to include foo.h everywhere you are making call to that function and where you are providing definition for that function.
Also if foo is a global function ( not inside any namespace ) then there is no need to include that foo.h in implementation file.
I am aware that definitions of C++ templated functions have to be placed in header files. However, for reasons of improved readability and structure of a (potentially) big library I am making, I separated the declarations from the implementations, into "mock" headers (which #include the implementation files, quite like this structure of files). Note that am I am aware that the implementation of templated functions must be included at compile time, and I am doing that.
In short, I have a "multiple definition" error when I add a non-templated function declaration into the implementation file. Long explanation with examples follows.
When the pair of "mock" header + implementation files only contain the declaration/implementation pair of the templated function, everything works fine. It also works fine when I add an implementation of a new templated function only in the implementation file.
Working example (I would #include "algo.h" in my main.cpp when I wanted to use this functionality):
"Mock" header file algo.h:
#ifndef ALGO_H
#define ALGO_H
namespace fl{
template <typename Compare>
void algo(.. non-templated args .., Compare order = std::less<int>());
}
#include "tpp/algo.cpp"
#endif // ALGO_H
Implementation file tpp/algo.cpp: (currently just algo.tpp)
Note: Using the tpp/.cpp file was in the initial version, now I am using a .tpp file per #πάντα ῥεῖ's suggestion, explanation in the end.
#ifndef TPP_ALGO
#define TPP_ALGO
#include "../algo.h"
namespace fl{
template <typename Compare>
void subFunctionality(Compare order, .. args ..){ /* impl */ }
template <typename Compare>
void algo(.. non-templated args .., Compare order){
subFunctionality(order, .. args ..);
// implementation
}
}
#endif // TPP_ALGO
The problem arises when I add a non-templated function implementation in the implementation file. (Non-working) example of the tpp/algo.cpp (currently just algo.tpp) (using the same algo.h):
#ifndef TPP_ALGO
#define TPP_ALGO
#include "../algo.h"
namespace fl{
template <typename Compare>
void subFunctionality(Compare order, .. args ..){ /* impl */ }
void moreSubFun(.. args ..) { /* impl */ }
template <typename Compare>
void algo( .. non-templated args ..., Compare order){
subFunctionality(order, .. args ..);
moreSubFun(.. args ..);
// more stuff
}
}
#endif // TPP_ALGO
I get the "multiple definition" error (from where I included it in main.cpp), like so:
obj/Release/main.o In function `fl::moreSubFun(...)':
main.cpp multiple definitions of `fl::moreSubFun(..)'
obj/Release/../tpp/algo.o:algo.cpp first defined here
Why does this happen only to non-templated functions, while it works fine for the templated, and more importantly, how do I solve this problem?
I looked all around SO, and I can't find anything useful :( Ideally, I am looking for something as close to my own file-structure as possible (but I'll take anything that works while still using some separation into "mock" .h + tpp/.cpp). Do I have to take out the additional sub-functionalities into a separate, non-templated pair of .h/.cpp files, or is there other solutions? (The sub-functionalities should ideally not be visible to the end-user).
I am reluctant to use inline when defining fl::moreSubFunc(..) as the function is pretty big (and I was taught inline should ideally only be used with small functions). This does solve the problem, but I'm looking to see if there is a different solution.
I am working in Code::Blocks, using gcc version 4.7.2. This is the initial reason my implementation file is tpp/.cpp (.cpp extension), since Code::Blocks does not support it by default. This is changed in the current implementation following #πάντα ῥεῖ's suggestion (look below).
Late edit (After I taught the solution was found) I taught #πάντα ῥεῖ's answer solves the problem. I tweaked Code::Blocks to accept .tpp files (either treating it as header or source files). Initially, this solution worked.
However, this solution worked only when the algo.h file was included in only one other file: when I included it only in main.cpp. However, as soon as I tried including it in another source file (e.g. algo2.cpp) that would use those algorithms (in addition to main.cpp), the multiple definition problem came back.
Bottom line, the problem still persists as soon as I include the algo.h in more than one file, and I am still looking for a solution.
Your problem occurs because function templates are treated differently at link time from "plain" free functions. Functions must obey the One Definition Rule (ODR); that is, they must be defined in no more than one translation unit. Otherwise, when you get to link time, you end up with multiple definition errors like the one you cited. This same rule also applies to classes, types, and objects in general.
This would seem to preclude the use of templates at all; they must be fully included in every translation unit in which they are used. However, the ODR makes an exception for a few cases. Quoting from Wikipedia:
Some things, like types, templates, and extern inline functions, can be defined in more than one translation unit. For a given entity, each definition must be the same. Non-extern objects and functions in different translation units are different entities, even if their names and types are the same.
This is why you don't run into multiple definition errors with the template functions. At link time, the linker finds the duplicate symbol definitions and removes all duplicates (as long as they are all equivalent; otherwise, this would be an error). Therefore, your program links successfully with exactly one definition of each required symbol.
For your case, your problem occurs because you are including non-template functions in more than one translation unit (everywhere that the .cpp file is included). There would be a few ways of fixing this:
If the template functions are part of a class, you could move the non-template functions to lie in that class as well. This would bring it under the symbol-deduplicating umbrella of the owning template class.
Mark the functions as inline.
Break the non-template functions out into another .cpp file that you then compile separately. That will be the only translation unit that houses them.
In general you should compile .cpp file separately and link it later. But if you want (or must) do it this way, mark all non-template functions as inline. This should help.
As a good rule of thumb:
"Never ever include a .cpp file."
You shouldn't give these template implementation files a .cpp extension. Your build system might include them automatically then.
The conventionally used extensions for such files are e.g. .tcc or .icc. Add these to your project, as you would add other header files.
Don't include them in the project as separately build and linked translation units, if they are used with an #include statement from another header file.
UPDATE:
As you were asking for Code Blocks specifically, you'll just need to tweak your file extension settings a bit, to get these files included in your project correctly, and have them syntax colored as usual:
1. Add the new file type to the file extension settings
2. Add the file type to the project file extension settings Project->Project Tree->Edit file types & categories
As soon a .tcc file is added to the project now, it will be opened using the text editor, and syntax colored as usual:
The corresponding .hpp file looks like this
When we design classes in Java, Vala, or C# we put the definition and declaration in the same source file. But in C++ it is traditionally preferred to separate the definition and declaration in two or more files.
What happens if I just use a header file and put everything into it, like Java?
Is there a performance penalty or something?
The answer depends on what kind of class you're creating.
C++'s compilation model dates back to the days of C, and so its method of importing data from one source file into another is comparatively primitive. The #include directive literally copies the contents of the file you're including into the source file, then treats the result as though it was the file you had written all along. You need to be careful about this because of a C++ policy called the one definition rule (ODR) which states, unsurprisingly, that every function and class should have at most one definition. This means that if you declare a class somewhere, all of that class's member functions should be either not defined at all or defined exactly once in exactly one file. There are some exceptions (I'll get to them in a minute), but for now just treat this rule as if it's a hard-and-fast, no-exceptions rule.
If you take a non-template class and put both the class definition and the implementation into a header file, you might run into trouble with the one definition rule. In particular, suppose that I have two different .cpp files that I compile, both of which #include your header containing both the implementation and the interface. In this case, if I try linking those two files together, the linker will find that each one contains a copy of the implementation code for the class's member functions. At this point, the linker will report an error because you have violated the one definition rule: there are two different implementations of all the class's member functions.
To prevent this, C++ programmers typically split classes up into a header file which contains the class declaration, along with the declarations of its member functions, without the implementations of those functions. The implementations are then put into a separate .cpp file which can be compiled and linked separately. This allows your code to avoid running into trouble with the ODR. Here's how. First, whenever you #include the class header file into multiple different .cpp files, each of them just gets a copy of the declarations of the member functions, not their definitions, and so none of your class's clients will end up with the definitions. This means that any number of clients can #include your header file without running into trouble at link-time. Since your own .cpp file with the implementation is the sole file that contains the implementations of the member functions, at link time you can merge it with any number of other client object files without a hassle. This is the main reason that you split the .h and .cpp files apart.
Of course, the ODR has a few exceptions. The first of these comes up with template functions and classes. The ODR explicitly states that you can have multiple different definitions for the same template class or function, provided that they're all equivalent. This is primarily to make it easier to compile templates - each C++ file can instantiate the same template without colliding with any other files. For this reason, and a few other technical reasons, class templates tend to just have a .h file without a matching .cpp file. Any number of clients can #include the file without trouble.
The other major exception to the ODR involves inline functions. The spec specifically states that the ODR does not apply to inline functions, so if you have a header file with an implementation of a class member function that's marked inline, that's perfectly fine. Any number of files can #include this file without breaking the ODR. Interestingly, any member function that's declared and defined in the body of a class is implicitly inline, so if you have a header like this:
#ifndef Include_Guard
#define Include_Guard
class MyClass {
public:
void DoSomething() {
/* ... code goes here ... */
}
};
#endif
Then you're not risking breaking the ODR. If you rewrite this as
#ifndef Include_Guard
#define Include_Guard
class MyClass {
public:
void DoSomething();
};
void MyClass::DoSomething() {
/* ... code goes here ... */
}
#endif
then you would be breaking the ODR, since the member function isn't marked inline and if multiple clients #include this file there will be multiple definitions of MyClass::DoSomething.
So to summarize - you should probably split up your classes into a .h/.cpp pair to avoid breaking the ODR. However, if you're writing a class template, you don't need the .cpp file (and probably shouldn't have one at all), and if you're okay marking every single member function of your class inline you can also avoid the .cpp file.
The drawback of putting definition in header files is as follows:-
Header file A - contains definition of metahodA()
Header file B - includes header file A.
Now let us say you change the definition of methodA. You would need to compile file A as well as B because of the inclusion of header file A in B.
The biggest difference is that every function is declared as an inline function. Generally your compiler will be smart enough that this won't be a problem, but worst case scenario it will cause page faults on a regular basis and make your code embarrassingly slow. Usually the code is separated for design reasons, and not for performance.
In general, it is a good practice to seperate implementation from headers. However, there are exceptions in cases like templates where the implementation goes in the header itself.
Two particular problems with putting everything in the header:
Compile times will be increased, sometimes greatly. C++ compile times are long enough that that's not something you want.
If you have circular dependencies in the implementation, keeping everything in headers is difficult to impossible. eg:
header1.h
struct C1
{
void f();
void g();
};
header2.h
struct C2
{
void f();
void g();
};
impl1.cpp
#include "header1.h"
#include "header2.h"
void C1::f()
{
C2 c2;
c2.f();
}
impl2.cpp
#include "header2.h"
#include "header1.h"
void C2::g()
{
C1 c1;
c1.g();
}
When dividing your code up into multiple files just what exactly should go into an .h file and what should go into a .cpp file?
Header files (.h) are designed to provide the information that will be needed in multiple files. Things like class declarations, function prototypes, and enumerations typically go in header files. In a word, "definitions".
Code files (.cpp) are designed to provide the implementation information that only needs to be known in one file. In general, function bodies, and internal variables that should/will never be accessed by other modules, are what belong in .cpp files. In a word, "implementations".
The simplest question to ask yourself to determine what belongs where is "if I change this, will I have to change code in other files to make things compile again?" If the answer is "yes" it probably belongs in the header file; if the answer is "no" it probably belongs in the code file.
Fact is, in C++, this is somewhat more complicated that the C header/source organization.
What does the compiler see?
The compiler sees one big source (.cpp) file with its headers properly included. The source file is the compilation unit that will be compiled into an object file.
So, why are headers necessary?
Because one compilation unit could need information about an implementation in another compilation unit. So one can write for example the implementation of a function in one source, and write the declaration of this function in another source needing to use it.
In this case, there are two copies of the same information. Which is evil...
The solution is to share some details. While the implementation should remain in the Source, the declaration of shared symbols, like functions, or definition of structures, classes, enums, etc., could need to be shared.
Headers are used to put those shared details.
Move to the header the declarations of what need to be shared between multiple sources
Nothing more?
In C++, there are some other things that could be put in the header because, they need, too, be shared:
inline code
templates
constants (usually those you want to use inside switches...)
Move to the header EVERYTHING what need to be shared, including shared implementations
Does it then mean that there could be sources inside the headers?
Yes. In fact, there are a lot of different things that could be inside a "header" (i.e. shared between sources).
Forward declarations
declarations/definition of functions/structs/classes/templates
implementation of inline and templated code
It becomes complicated, and in some cases (circular dependencies between symbols), impossible to keep it in one header.
Headers can be broken down into three parts
This means that, in an extreme case, you could have:
a forward declaration header
a declaration/definition header
an implementation header
an implementation source
Let's imagine we have a templated MyObject. We could have:
// - - - - MyObject_forward.hpp - - - -
// This header is included by the code which need to know MyObject
// does exist, but nothing more.
template<typename T>
class MyObject ;
.
// - - - - MyObject_declaration.hpp - - - -
// This header is included by the code which need to know how
// MyObject is defined, but nothing more.
#include <MyObject_forward.hpp>
template<typename T>
class MyObject
{
public :
MyObject() ;
// Etc.
} ;
void doSomething() ;
.
// - - - - MyObject_implementation.hpp - - - -
// This header is included by the code which need to see
// the implementation of the methods/functions of MyObject,
// but nothing more.
#include <MyObject_declaration.hpp>
template<typename T>
MyObject<T>::MyObject()
{
doSomething() ;
}
// etc.
.
// - - - - MyObject_source.cpp - - - -
// This source will have implementation that does not need to
// be shared, which, for templated code, usually means nothing...
#include <MyObject_implementation.hpp>
void doSomething()
{
// etc.
} ;
// etc.
Wow!
In the "real life", it is usually less complicated. Most code will have only a simple header/source organisation, with some inlined code in the source.
But in other cases (templated objects knowing each others), I had to have for each object separate declaration and implementation headers, with an empty source including those headers just to help me see some compilation errors.
Another reason to break down headers into separate headers could be to speed up the compilation, limiting the quantity of symbols parsed to the strict necessary, and avoiding unecessary recompilation of a source who cares only for the forward declaration when an inline method implementation changed.
Conclusion
You should make your code organization both as simple as possible, and as modular as possible. Put as much as possible in the source file. Only expose in headers what needs to be shared.
But the day you'll have circular dependancies between templated objects, don't be surprised if your code organization becomes somewhat more "interesting" that the plain header/source organization...
^_^
in addition to all other answers, i will tell you what you DON'T place in a header file:
using declaration (the most common being using namespace std;) should not appear in a header file because they pollute the namespace of the source file in which it is included.
What compiles into nothing (zero binary footprint) goes into header file.
Variables do not compile into nothing, but type declarations do (coz they only describe how variables behave).
functions do not, but inline functions do (or macros), because they produce code only where called.
templates are not code, they are only a recipe for creating code. so they also go in h files.
In general, you put declarations in the header file and definitions in the implementation (.cpp) file. The exception to this is templates, where the definition must also go in the header.
This question and ones similar to it has been asked frequently on SO - see Why have header files and .cpp files in C++? and C++ Header Files, Code Separation for example.
Mainly header file contain class skeleton or declaration (does not change frequently)
and cpp file contains class implementation (changes frequently).
Header (.h)
Macros and includes needed for the interfaces (as few as possible)
The declaration of the functions and classes
Documentation of the interface
Declaration of inline functions/methods, if any
extern to global variables (if any)
Body (.cpp)
Rest of macros and includes
Include the header of the module
Definition of functions and methods
Global variables (if any)
As a rule of thumb, you put the "shared" part of the module on the .h (the part that other modules needs to be able to see) and the "not shared" part on the .cpp
PD: Yes, I've included global variables. I've used them some times and it's important not to define them on the headers, or you'll get a lot of modules, each defining its own variable.
Your class and function declarations plus the documentation, and the definitions for inline functions/methods (although some prefer to put them in separate .inl files).
the header file (.h) should be for declarations of classes, structs and its methods, prototypes, etc. The implementation of those objects are made in cpp.
in .h
class Foo {
int j;
Foo();
Foo(int)
void DoSomething();
}
I'd expect to see:
declarations
comments
definitions marked inline
templates
the really answer though is what not to put in:
definitons (can lead to things being multiply defined)
using declarations/directives (forces them on anyone including your header, can cause nameclashes)
The header Defines something but doesn't tell anything about the implementation. ( Excluding Templates in this "metafore".
With that said, you need to divide "definitions" into sub-groups, there are, in this case, two types of definitions.
You define the "layout" of your strucutre, telling only as much as is needed by the surrounding usage groups.
The definitions of a variable, function and a class.
Now, I am of course talking about the first subgroup.
The header is there to define the layout of your structure in order to help the rest of the software use the implementation. You might want to see it as an "abstraction" of your implementation, which is vaughly said but, I think it suits quite well in this case.
As previous posters have said and shown you declare private and public usage areas and their headers, this also includes private and public variables. Now, I don't want to go into design of the code here but, you might want to consider what you put in your headers, since that is the Layer between the end user and the implementation.
Header files - shouldn't change during development too often -> you should think, and write them at once (in ideal case)
Source files - changes during implementation