So if I include iostream twice in my project why is that valid? Wouldn't the linker see that there are two definitions of it and report a error, but it works?
Wouldn't the linker see that there are two definitions of it and report a error, but it works?
Yes. Which is why headers are not supposed to contain definitions, only declarations. There are a few exceptions to this rule:
1. Static integer member constants can be defined in class definitions.
2. inline functions must be defined in headers (their definition must be visible to the compiler at the call site for inlining to work).
3. Member functions may be defined in the class definition. This implicitly makes the functions inlineable.
4. The definition of template functions or classes must be visible wherever they may be called. This usually involves putting the entire definition of the class and all its functions in a header. This doesn't cause linker errors because template definitions are only seen by the compiler. The linker only sees the final template instantiations (presumably it merges instances of the same template function in different translation units).
One more question, if I define a class and I put several function definitions in it, except I put the definition of one member function in a cpp file and the prototype in the class header, does that mean that the class in the header is still a declaration and not a definition?
A class declaration is of the form class Identifier; with possible optional template syntactic aggregates. If you had to use curly braces, it's not a declaration anymore, but a definition. Class definitions may be placed in headers because, unlike data and functions, they're invisible to the linker.
You need to understand the difference between a declaration and a definition.
Header files contain only declarations. Declarations do not generate executable code. Therefore there is nothing to been seen by the linker.
Classes don't generate code in itself. For example, the program
class A{ short a; int b; }
generates no code. Classes are a way to tell the compiler how the data should be laid out in memory, and the compiler uses this information to generate the code. For example, given the code
1 2
A o;
o.b = 42;
and the previous definition, the compiler knows that it has to generate the code to add sizeof(short) to the pointer that points to the instance of o (this pointer exists at the machine level, not at the C++ level) and then store at that memory location, interpreted as an int, the value 42. To do all this, the compiler needs to know the structure of the class, but once it has generated the code, it has no other use of it. The linker only understands about code and data, not about classes (note that in C++ toolchains, the C++ linker and the C linker are one and the same).
Yes but what if the entire class definition was in the header, or only a couple functions, would that be considered a definition or a declaration, because you are defining a bit of the class.
edit: Ok thanks Helios!
But if I do define a function in the header I should not include it twice or I should make it inline?
He's asking about including the same header in different translation units. Include guards are relevant within the same translation unit.
But if I do define a function in the header I should not include it twice or I should make it inline?
A function may be defined in a header only if its an inline or template function, or if the header is included in a single translation unit, or the linker will complain about duplicate definitions.
It's easier to simply not define functions in headers than to keep track of where you included some file.