C++ Header Files, Code Separation - c++

I am new to C++ and I had a few general questions about code separation. I have currently built a small application, all in one file. What I want to do now is convert this into separate files such that they contain similar code or whatnot. My real question right now is, how do I know how to separate things? What is the invisible margin that code should be separated at?
Also, what's the point of header files? Is it to forward declare methods and classes so I can use them in my code before they are included by the linker during compilation?
Any insight into methods or best practises would be great, thanks!

Header files should contain class and function declarations.
Source files contain class and function definitions.
It is standard practice (i.e. read easier) to have one declaration per header file and one definition per source file, though for small (read simpler helper) objects you sometimes group them with related more substantial objects.
Example: Class Menu
Menu.h: Contains the Menu declaration.
Menu.cpp: Contains the Menu definition.
The reason header files contain the declarations is so that you can include them from multiple source files and thus each source file has exactly the same definition of each class and function.
Consider it this way:
If you did not have header files then you would need to have the class and/or function declarations (without) definitions in every source file, this means a copy of the same declaration in every file. Thus if you modify a class you need to make the same modification in every file. By the use of a header file you have the declaration in one place and thus only one object to modify.

First, you should not put anything into headers that is not needed to be visible by any other file, other than the one that needs it. Then, let's define something we need below.
Translation Unit
A Translation Unit is the current code being compiled, and all the code included
by it, directly or indirectly. One Translation unit translates to one .o / .obj file.
Program
That's all your .o / .obj files linked together into one binary file that can be
executed to form a process.
What are the main points of having different translation units?
Reduce dependencies, so that if you change one method of one class, you don't have to recompile all the code of your program, but only the affected translation unit. An
Reduce possible name clashes by having translation unit local names, that are not visible by other translation unit when linking them together.
Now, how can you split your code into different translation units? The answer is there is no "so you do it!", but you have to consider it on a case-by-case basis. It's often clear, since you have different classes, which can and should be put in different translation units:
foo.hpp:
/* Only declaration of class foo we define below. Note that a declaration
* is not a definition. But a definition is always also a declaration */
class foo;
/* definition of a class foo. the same class definition can appear
in multiple translation units provided that each definition is the same
basicially, but only once per translation unit. This too is called the
"One Definition Rule" (ODR). */
class foo {
/* declaration of a member function doit */
void doit();
/* definition of an data-member age */
int age;
};
Declare some free functions and objects:
/* if you have translation unit non-local (with so-called extern linkage)
names, you declare them here, so other translation units can include
your file "foo.hpp" and use them. */
void getTheAnswer();
/* to avoid that the following is a definition of a object, you put "extern"
in front of it. */
extern int answerCheat;
foo.cpp:
/* include the header of it */
#include "foo.hpp"
/* definition of the member function doit */
void foo::doit() {
/* ... */
}
/* definition of a translation unit local name. preferred way in c++. */
namespace {
void help() {
/* ... */
}
}
void getTheAnswer() {
/* let's call our helper function */
help();
/* ... */
}
/* define answerCheat. non-const objects are translation unit nonlocal
by default */
int answerCheat = 42;
bar.hpp:
/* so, this is the same as above, just with other classes/files... */
class bar {
public:
bar(); /* constructor */
};
bar.cpp:
/* we need the foo.hpp file, which declares getTheAnswer() */
#include "foo.hpp"
#include "bar.hpp"
bar::bar() {
/* make use of getTheAnswer() */
getTheAnswer();
}
Please note that names within an anonymous namespace (as above) do not clash since they appear to be translation unit local. in reality they are not, they just have unique names so that they do not clash. if you really want (there is little reason to) translation unit local names (for example because of compatibility with c so C code can call your function) you can do it like this:
static void help() {
/* .... */
}
The ODR also says that you cannot have more than one definition of any object or non-inline function in one program (classes are types, not objects, so it doesn't apply to them). So you have to watch out not to put non-inline functions into headers, or not putting objects like "int foo;" in headers. That will cause linker errors then when the linker tries to link the translation units including those headers together.
I hope i could help you a bit. Now that was a long answer, there are indeed errors somewhere. I know that a translation unit strictly is defined another way (output of the pre-processor). But i think it would not add big value to include that into the above, and it would confuse the matter. Please feel free to slap me if you find real bugs :)

Deciding how to separate your code into different classes/functions is one of main tasks of programing. There are many different guidelines on how to do this and I would recommend reading some tutorials on C++ and Object Oriented Design to get you started.
Some basic guidelines will be
Put things together which are used
together
Create classes for domain objects
(eg files, collections etc)
Header files allow you to declare a class or function and then use it in several different source files. For example, if you declare a class in a header file
// A.h
class A
{
public:
int fn();
};
You can then use this class in several source files:
// A.cpp
#include "A.h"
int A::fn() {/* implementation of fn */}
//B.cpp
#include "A.h"
void OtherFunction() {
A a;
a.fn();
}
So header files enable you to separate the declaration from the implementation. If you were to put everything (declaration and implementation) in a source file (eg A.cpp) then try to include that in a second file, eg
// B.cpp
#include "A.cpp" //DON'T do this!
Then you could compile B.cpp but when you try to link your program the linker will complain that you have multiply defined objects - this is because you have multiple copies of the implementation of A.

Suggestion:
1. Have a design ready for your application now.
2. Based on the design, create necessary objects that interact with each other.
3. Refactor or completely change the existing code to suit the newly created design.
Header files provide an interface to the other classes that might use it's functionality.

Related

Use header-only (+implementation .h files) across multiple files in C++ project [duplicate]

I have a c++ header file containing a class.
I want to use this class in several projects, bu I don't want to create a separate library for it, so I'm putting both methods declarations and definitions in the header file:
// example.h
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
namespace test_ns{
class TestClass{
public:
void testMethod();
};
void TestClass::testMethod(){
// some code here...
}
} // end namespace test_ns
#endif
If inside the same project I include this header from more than one cpp file, I get an error saying "multiple definition of test_ns::TestClass::testMethod()", while if I put the method definition inside the class body this does not happen:
// example.h
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
namespace test_ns{
class TestClass{
public:
void testMethod(){
// some code here...
}
};
} // end namespace test_ns
#endif
Since the class is defined inside a namespace, shouldn't the two forms be equivalent? Why is the method considered to be defined twice in the first case?
Inside the class body is considered to be inline by the compiler.
If you implement outside of body, but still in header, you have to mark the method as 'inline' explicitly.
namespace test_ns{
class TestClass{
public:
inline void testMethod();
};
void TestClass::testMethod(){
// some code here...
}
} // end namespace test_ns
Edit
For myself it often helps to solve these kinds of compile problems by realizing that the compiler does not see anything like a header file. Header files are preprocessed and the compiler just sees one huge file containing every line from every (recursively) included file. Normally the starting point for these recursive includes is a cpp source file that is being compiled.
In our company, even a modest looking cpp file can be presented to the compiler as a 300000 line monster.
So when a method, that is not declared inline, is implemented in a header file, the compiler could end up seeing void TestClass::testMethod() {...} dozens of times in the preprocessed file. Now you can see that this does not make sense, same effect as you'd get when copy/pasting it multiple times in one source file.
And even if you succeeded by only having it once in every compilation unit, by some form of conditional compilation ( e.g. using inclusion brackets ) the linker would still find this method's symbol to be in multiple compiled units ( object files ).
These are not equivalent. The second example given has an implicit 'inline' modifier on the method and so the compiler will reconcile multiple definitions itself (most likely with internal linkage of the method if it isn't inlineable).
The first example isn't inline and so if this header is included in multiple translation units then you will have multiple definitions and linker errors.
Also, headers should really always be guarded to prevent multiple definition errors in the same translation unit. That should convert your header to:
#ifndef EXAMPLE_H
#define EXAMPLE_H
//define your class here
#endif
Don't put a function/method definition in an header file unless they are inlined (by defining them directly in a class declaration or explicity specified by the inline keyword)
header files are (mostly) for declaration (whatever you need to declare). Definitions allowed are the ones for constants and inlined functions/methods (and templates too).
Actually it is possible to have definitions in a single header file (without a separate .c/.cpp file) and still be able to use it from multiple source files.
Consider this foobar.h header:
#ifndef FOOBAR_H
#define FOOBAR_H
/* write declarations normally */
void foo();
void bar();
/* use conditional compilation to disable definitions when necessary */
#ifndef ONLY_DECLARATIONS
void foo() {
/* your code goes here */
}
void bar() {
/* your code goes here */
}
#endif /* ONLY_DECLARATIONS */
#endif /* FOOBAR_H */
If you use this header in only one source file, include and use it normally.
Like in main.c:
#include "foobar.h"
int main(int argc, char *argv[]) {
foo();
}
If there're other source files in your project which require foobar.h, then #define ONLY_DECLARATIONS macro before including it.
In use_bar.c you may write:
#define ONLY_DECLARATIONS
#include "foobar.h"
void use_bar() {
bar();
}
After compilation use_bar.o and main.o can be linked together without errors, because only one of them (main.o) will have implementation of foo() and bar().
That's slightly non-idiomatic, but it allows to keep definitions and declarations together in one file. I feel like it's a poor man's substitute for true modules.
Your first code snippet is falling foul of C++'s "One Definition Rule" - see here for a link to a Wikipedia article describing ODR. You're actually falling foul of point #2 because every time the compiler includes the header file into a source file, you run into the risk of the compiler generating a globally visible definition of test_ns::TestClass::testMethod(). And of course by the time you get to link the code, the linker will have kittens because it will find the same symbol in multiple object files.
The second snippet works because you've inlined the definition of the function, which means that even if the compiler doesn't generate any inline code for the function (say, you've got inlining turned off or the compiler decides the function is too big to inline), the code generated for the function definition will be visible in the translation unit only, as if you'd stuck it in an anonymous namespace. Hence you get multiple copies of the function in the generated object code that the linker may or may not optimize away depending on how smart it is.
You could achieve a similar effect in your first code snippet by prefixing TestClass::testMethod() with inline.
//Baseclass.h or .cpp
#ifndef CDerivedclass
#include "Derivedclass.h"
#endif
or
//COthercls.h or .cpp
#ifndef CCommonheadercls
#include "Commonheadercls.h"
#endif
I think this suffice all instances.

Separating C++ Class Code into Multiple Files, what are the rules?

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.

Why do I explicitly have to declare functions inline here?

Okay, up until now, I thought that functions defined in header files are treated like inline functions, just like template stuff, defined once, and all that.
I also use inclusion guards, yet I still got linker errors of multiple defined objects, and I know that is because of all those different units duplicating stuff the linker tries to pick out which item is the right one.
I also know that inline is merely a suggestion, and might not even get used by the compiler, etc.
Yet I have to explicitly define all those small functions in that little header only toolset I wrote.
Even if the functions were huge, I'd have to declare them inline, and the compiler would still possibly disregard the hint.
Yet I have to define them so anyway.
Example:
#ifndef texture_math_h__
#define texture_math_h__
float TexcoordToPixel(float coord, float dimension)
{
return coord * dimension;
}
float PixelToTexcoord(float pixel, float dimension)
{
return pixel / dimension;
}
float RecalcTexcoord(float coord,float oldDimension, float newDimension)
{
return PixelToTexcoord(TexcoordToPixel(coord,oldDimension),newDimension);
}
#endif // texture_math_h__
Errors are , blabla already defined in xxx.obj, for each unit that includes the file
When I declare all of those inline, it links correctly.
What's the reason for that? It's not a huge problem, and heck, optimizations probably inline stuff found in cpp, too, right?
I'm just curious about the why here, hope it's not too much of a duplicate and thank you for your time.
Inclusion guards only guard against the code being included twice in the same translation unit. So if you have multiple files that include the same header, the code is included multiple times. Functions defined in a header are not inline by default, so this will give you linker errors - you need to define those function with the inline keyword, unless they are member functions of a class.
Also, note that names that contain double-underscores are reserved for the purposes of the C++ implementation - you are not allowed to create such names in your own code.
Member functions are potencially inlined - you can't force inlining! - if (a) they are defined inside the class or if (b) you use the inline-clause in the definition. Note if you are using the inline-clause you shouldn't define the function in the header - the only exception would be templates as these are "special".
As you just updated the question:
Every user of this header will have a definition of the functions -> multiple defintions. You need to separate definition and declaration!
It's all about the one definition rule. This states that you can only have one definition for each non-inline function (along with various other types of entity) in a C++ program across all the translation units that you link in to make the program.
Marking a function inline enables an exception to the usual one definition rule. It states (paraphrased) that you can have one definition of an inline function per translation unit provided that all the definitions match and that a definition is provided in each translation in which the inline function is used.
Include guards will prevent you from accidentally providing more than one definition per translation unit by including the header file containing the definitions multiple times.
To satisfy the one definition rule for a non-inline function you would still have to ensure that there is only one translation unit containing the function definitions. The usualy way to do this is by only declaring the functions in the header file and having a single source file containing the definitions.

Is is a good practice to put the definition of C++ classes into the header file?

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();
}

How can I avoid including class implementation files?

Instead of doing
#include "MyClass.cpp"
I would like to do
#include "MyClass.h"
I've read online that not doing so is considered bad practice.
Separate compilation in a nutshell
First, let's get some quick examples out there:
struct ClassDeclaration; // 'class' / 'struct' mean almost the same thing here
struct ClassDefinition {}; // the only difference is default accessibility
// of bases and members
void function_declaration();
void function_definition() {}
extern int global_object_declaration;
int global_object_definition;
template<class T> // cannot replace this 'class' with 'struct'
struct ClassTemplateDeclaration;
template<class T>
struct ClassTemplateDefinition {};
template<class T>
void function_template_declaration();
template<class T>
void function_template_definition() {}
Translation Unit
A translation unit (TU) is a single source file (should be a **.cpp* file) and all the files it includes, and they include, etc. In other words: the result of preprocessing a single file.
Headers
Include guards are a hack to work around lack of a real module system, making headers into a kind of limited module; to this end, including the same header more than once must not have an adverse affect.
Include guards work by making subsequent #includes no-ops, with the definitions available from the first include. Because of their limited nature, macros which control header options should be consistent throughout a project (oddball headers like <assert.h> cause problems) and all #includes of public headers should be outside of any namespace, class, etc., usually at the top of any file.
See my include guard naming advice, including a short program to generate include guards.
Declarations
Classes, functions, objects, and templates may be declared almost anywhere, may be declared any number of times, and must be declared before referring to them in any way. In a few weird cases, you can declare classes as you use them; won't cover that here.
Definitions
Classes may be defined at most once[1] per TU; this typically happens when you include a header for a particular class. Functions and objects must be defined once in exactly one TU; this typically happens when you implement them in a **.cpp* file. However, inline functions, including implicitly inline functions inside class definitions, may be defined in multiple TUs, but the definitions must be identical.
For practical purposes[2], templates (both class templates and function templates) are defined only in headers, and if you want to use a separate file, then use another header[3].
[1] Because of the at-most-once restriction, headers use include guards to prevent multiple inclusion and thus multiple definition errors.
[2] I won't cover the other possibilities here.
[3] Name it blahblah_detail.hpp, blahblah_private.hpp, or similar if you want to document that it's non-public.
Guidelines
So, while I'm sure everything above is all a big ball of mud so far, it's less than a page on what should take up a few chapters, so use it as a brief reference. Understanding the concepts above, however, is important. Using those, here's a short list of guidelines (but not absolute rules):
Always name headers consistently in a single project, such as **.h* for C and **.hpp* for C++.
Never include a file which is not a header.
Always name implementation files (which are going to be directly compiled) consistently, such as **.c* and **.cpp*.
Use a build system which can compile your source files automatically. make is the canonical example, but there are many alternatives. Keep it simple in simple cases. For example, make can be used its built-in rules and even without a makefile.
Use a build system which can generate header dependencies. Some compilers can generate this with command-line switches, such as -M, so you can make a surprisingly useful system easily.
Build Process
(Here's the tiny bit that answers your question, but you need most of the above in order to get here.)
When you build, the build system will then go through several steps, of which the important ones for this discussion are:
compile each implementation file as a TU, producing an object file (**.o*, **.obj*)
each is compiled independently of the others, which is why each TU needs declarations and definitions
link those files, along with libraries specified, into a single executable
I recommend you learn the rudiments of make, as it is popular, well-understood, and easy to get started with. However, it's an old system with several problems, and you'll want to switch to something else at some point.
Choosing a build system is almost a religious experience, like choosing an editor, except you'll have to work with more people (everyone working on the same project) and will likely be much more constrained by precedent and convention. You can use an IDE which handles the same details for you, but this has no real benefit from using a comprehensive build system instead, and you really should still know what it's doing under the hood.
File Templates
example.hpp
#ifndef EXAMPLE_INCLUDE_GUARD_60497EBE580B4F5292059C8705848F75
#define EXAMPLE_INCLUDE_GUARD_60497EBE580B4F5292059C8705848F75
// all project-specific macros for this project are prefixed "EXAMPLE_"
#include <ostream> // required headers/"modules"/libraries from the
#include <string> // stdlib, this project, and elsewhere
#include <vector>
namespace example { // main namespace for this project
template<class T>
struct TemplateExample { // for practical purposes, just put entire
void f() {} // definition of class and all methods in header
T data;
};
struct FooBar {
FooBar(); // declared
int size() const { return v.size(); } // defined (& implicitly inline)
private:
std::vector<TemplateExample<int> > v;
};
int main(std::vector<std::string> args); // declared
} // example::
#endif
example.cpp
#include "example.hpp" // include the headers "specific to" this implementation
// file first, helps make sure the header includes anything it needs (is
// independent)
#include <algorithm> // anything additional not included by the header
#include <iostream>
namespace example {
FooBar::FooBar() : v(42) {} // define ctor
int main(std::vector<std::string> args) { // define function
using namespace std; // use inside function scope, if desired, is always okay
// but using outside function scope can be problematic
cout << "doing real work now...\n"; // no std:: needed here
return 42;
}
} // example::
main.cpp
#include <iostream>
#include "example.hpp"
int main(int argc, char const** argv) try {
// do any global initialization before real main
return example::main(std::vector<std::string>(argv, argv + argc));
}
catch (std::exception& e) {
std::cerr << "[uncaught exception: " << e.what() << "]\n";
return 1; // or EXIT_FAILURE, etc.
}
catch (...) {
std::cerr << "[unknown uncaught exception]\n";
return 1; // or EXIT_FAILURE, etc.
}
This is called separate compilation model. You include class declarations into each module where they are needed, but define them only once.
In addition to hiding implementation details in cpp files (check other replies), you can additionally hide structure details by class forward declaration.
class FooPrivate;
class Foo
{
public:
// public stuff goes here
private:
FooPrivate *foo_private;
};
The expression class FooPrivate says that FooPrivate is completely defined somewhere else (preferably in the same file where Foo's implementation resides, before Foo's stuff comes. This way you make sure that implementation details of Foo(Private) aren't exposed via the header file.
You needn't include .c or .cpp files - the compiler will compile them regardless whether they're #included in other files or not. However, the code in the .c/.cpp files is useless if the other files are unaware of the classes/methods/functions/global vars/whatever that's contained in them. And that's where headers come into play. In the headers, you only put declarations, such as this one:
//myfile.hpp
class MyClass {
public:
MyClass (void);
void myMethod (void);
static int myStaticVar;
private:
int myPrivateVar;
};
Now, all .c/.cpp files that will #include "myfile.hpp" will be able to create instances of MyClass, operate on myStaticVar and call MyClass::myMethod(), even though there's no actual implementation here! See?
The implementation (the actual code) goes into myfile.cpp, where you tell the compiler what all your stuff does:
//myfile.cpp
int MyClass::myStaticVar = 0;
MyClass::MyClass (void) {
myPrivateVar = 0;
}
void MyClass::myMethod (void) {
myPrivateVar++;
}
You never include this file anywhere, it's absolutely not necessary.
A tip: create a main.hpp (or main.h, if you prefer - makes no difference) file and put all the #includes there. Each .c/.cpp file will then only need to have have this line: #include "main.hpp". This is enough to have access to all classes, methods etc. you declared in your entire project :).
You should not include a source file (.c or .cpp). Instead you should include the corresponding header file(.h) containing the declarations. The source files needs to be compiled separately and linked together to get the final executable.
Cpp files should be defined in your compiler script to be compiled as object files.
What ide are you using?
I am going to assume you are compiling with gcc, so here is the command to compile two .cpp files into one executable
gcc -o myclasses.out myclass.cpp myotherclass.cpp
You should only use #include to include class definitions, not the implentation
One thing you will want to watch out for when including you class declarations from a .h/.hpp is make sure it only ever gets included once. If you don't do this you will get some possibly cryptic compiler errors that will drive you up the wall.
To do this you need to tell the compiler, using a #define, to include the file only if the #define does not already exist.
For example (MyClass.h):
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass
{
// Memebers and methods
}
#endif
// End of file
This will guarantee your class declaration only gets included once even if you have it included in many different .cpp files.