Hi,

I'm new to C++ but I have a Java background. Up until now I have been using header files to define my external classes.

However, I've been reading a book, C++ How to Program, and they use the header as an interface (define the prototypes of a class, I think they're called), and use another file (.cpp) to define the class functions.

They don't say why they do this. My functions work fine in the header file, and in Java you use the one file to define an external class. I just think it's just more typing you have to do and I don't see, yet, any advantages to it.

Can some enlighten me? Should I continue using header files this way?

Thanks

Well for small projects it ok to put everything in the header files, but as the project grows it will become more and more inconvenient. Since you have read stuff on C++ I will not repeat to much that the "philosophy" behind headers and cpps is to declare classes and functions in the header and implement (or define) them in the cpp.

In practice, when you compile a C++ project, you typically compile a bunch of cpp files together in an executable, an object file (.o), a static library (.a or .lib) or a shared library (.so or .dll). These contain the executable code, already compiled. So in the case of object files and static libraries, they contain the compiled version of your implementation (in the cpp files) and what they contain is declared in all the header files relevant to which cpp files you compiled into these object files and static libraries.

So.. what difference does it make to put code in cpp or header? Well header files are included all the time by other headers, other libraries, other parts of your project in general (think of it as other packages, in Java). So the more code you put in the header files the more stuff you require the compiler to compile for every individual part of project you are compiling. This will increase code size, and worse, increase compilation times (and it will get very annoying, very quickly!). Putting code in C++ files and nothing but the trivial code (like accessor methods of a class and such) in the header just makes thing compile faster.

But even more important, it allows you to decouple the code. This means that if you decide to change the implementation of your class methods or other functions. If you can do this without changing the header because it contains only an interface and no real important code, it will allow you to only recompile the cpp files you changed and all the other parts of your project will only need to be re-linked, which is very quick, and not re-compiled.

Take my current project as an example of proportions that make the building or overall compilation quite easy and quick (unless it is an actual full re-compilation):
Roughly 35 000 lines of code;
Roughly 80 header / cpp pairs;
Roughly 20 static libraries;
Around 6 final executables (not including unit-testing apps)
This stratification makes the code very independent and thus I very rarely need to compile everything, because all the meaningful code is in cpp files and are compiled into static libraries and at the end the executable are usually very simple and just get linked back to updated libraries when the code has changed.

EDIT: Another important issue I forgot to mention, is that if you have global functions (not member of a class) that have their definitions in the header file, you should put the keyword "inline" before their definition otherwise you might run into problems of multiple definition of functions, if you compile two cpp files that both include that header into the same executable or library.

Edited 6 Years Ago by mike_2000_17: n/a

Comments
Nicely explained
excellent summary

No, use header files to define the skeleton of a class. And if possible, use .cpp
file to define those classes. One of the main reason why one would do this is for
organizations reasons. In some cases, having the definition in the .h file can lead
to multiple definition errors in C++. Another reason is because it makes your code cleaner. And also, when you make a slight change to the header file, you will have to
compile every file that uses the header file, while if you had a .cpp, then you would
only need to compile the .cpp.

I use inline functions frequently in header files but they are really only useful for functions that are only one or two lines. If you do this for functions on in a c++ class then you must declare them with the inline keyword (or __inline depending on the compiler). If you don't then you will wind up with duplicate function declarations when the header file is included in two or more *.cpp or *.c files. inline is not necessary for cass methods

Note that compilers are not required to honor the inine keyword. inline is only a hint to the compiler how to optimize the program and they are free to do as they wish.

class Foo
{
public:
   Foo() { _x = 0; }; // an inline constructor
   int getX() {return _x;} // another inline method
   void setX(int x) {_x = x;} // another inline method
private:
   int _x;
};

// an inline function
_inline int bar(int x, int y)
{
   return x*y;
}

If you use Visual Studio Pro version and create a COM or ATL project the IDE will generate several header files that contain inline class methods that are 20-30 or more lines long. I usually move them into an implementatin file to make the header file easier to read.

You will also see inline class methods used extensiely in the STL header files such as <string>, <vector>, <list>, <fstream> etc. I believe the reason is because they are templates. I won't even look at those files because they are sooo awful to read.

Edited 6 Years Ago by Ancient Dragon: n/a

You will also see inline class methods used extensiely in the STL header files such as <string>, <vector>, <list>, <fstream> etc. I believe the reason is because they are templates.

That's right! When it comes to templates, it's a whole bunch of additional issues with respect to code in header or cpp files. Look up "template instantiation", or read this.

This article has been dead for over six months. Start a new discussion instead.