It’s often useful to separate the class interface (*.h
)
from the class implementation (*.cc
).
Foo.h | Foo.cc |
---|---|
#ifndef FOO_H_INCLUDED #define FOO_H_INCLUDED #include <iostream> class Foo { public: Foo(); int get_data() const; private: double data; }; std::ostream & operator<<(std::ostream &, const Foo &); #endif /* FOO_H_INCLUDED */ |
#include "Foo.h" using namespace std; Foo::Foo() : data(42.0) { } int Foo::get_data() const { return data; } ostream &operator<<(ostream &os, const Foo &f) { return os << f.get_data(); } |
The *.h
file only contains the method declarations (signatures),
function declarations (for non-member functions & operators) and
declarations of data members. The *.cc
file contains the actual
code for the methods and functions. Neither one contains main
.
*.h
file as containing the interface,
the contract between you, the developer, and the end user.
We can develop the interface long before we have to
actually write the code. It’s easier to consider the merits
of the interface unencumbered by the details of the implementation.
*.cc
.
Foo.h
and Foo.o
to your customers. This keeps your
implementation source code out of your customer’s hands.
“But it’s more typing!”
If you’re afraid of typing, then you have certainly chosen the wrong profession, and the wrong century to live in.
Compile the code like this:
g++ -Wall main.cc Foo.cc
Note that you should not compile the *.h
file. That will
result in a *.gch
(compiled header) file, which will cause no end of
trouble. Remove it if you ever find it.
If you do this with a Makefile
, make sure to have main.cc
also
depend upon Foo.h
. After all, if you change Foo.h
(say, by
adding a member variable) then you must recompile main.cc
, because
the size of Foo
has changed.