Let's look at a program that deals with some geometric shapes.
There are some parts of the program that are generic and could be separated for possible reused.
What are the parts that are reusable?
When we separate a set of code into its own files, we call it a module. Although modules can contain sets of functions or sets of classes, we often use a single module for each class.
To create a C++ module for our Point class, we need to create
2 new source code files:
.h file and a
.cpp file. It is typical for
the base name of those files to be the same, and to relate to the class
name. Thus, we'll name them:
Since this module only contains the Point class, we'll also need a
module for our Rectangle class, and a file for the main program (let's
What files will we need for a Rectangle class module?
We've already broken the original program (
into these files and made them available for you to download.
Download all those files, including a make file that we'll use
main.cppuses the Point class, it includes the Point header:
When including a non-standard header file (like one you wrote), list its name in double quotes (like above). When including system header files, list their names in angle brackets, as in:
How does the implementation file
Point.cpp get the
Point class definition?
One thing is missing from our new Point module...The header should be wrapped to prevent multiple inclusion.
Header files, like our header for the Point class (
contain class definitions.
The code in a header should only be included into a
.cpp file once; otherwise, the compiler may complain and
refuse to compile the
.cpp file. If a header does get
included into a
.cpp file more than once, we call this
Multiple inclusion is likely in the following form:
#include "Point.h" #include "Rectangle.h"
In this case, you might get some compiler error like:
In file included from Rectangle.h:11, from main.cpp:10: Point.h:9: redefinition of `class Point' Point.h:20: previous definition here
I.e., it did not like the fact that
Point gets defined twice
To solve the problem of multiple inclusion, we wrap the header by doing the following... Put the whole header inside an if-not-defined construct, like:
where#ifndef POINT_H #define POINT_H CONTENTS OF Point.h #endif
POINT_His unique to the file
POINT_H) is to take the file name of the header (e.g.,
This usually gives a unique symbol.
Being wrapped, the first time
Point.h is included:
the symbol#include "Point.h" // POINT_H not defined yet, // but once this #include is // done it will be.
POINT_Hwill not be defined and the code in the header will be compiled. Later, if the header is included again (directly or indirectly):
in the same source file, then the code will be skipped since#include "Rectangle.h" // This tries to include Point.h.
POINT_His already defined (i.e., it got defined the first time we included
Go ahead and wrap
Point.h (i.e., edit
Now we would like to compile and link our program, which is made up
of multiple files, i.e., header (
.h) and implementation
We can use
g++ as usual, and just need to specify the
source code files that make up the program...
% g++ -o main main.cpp Point.cpp Rectangle.cpp
We now have an executable
main that can be run:
Enter some values to test it.
Now, let's change the code.
Rectangle.cpp and change the method
so that it uses the
height() method for now).
Once you've made the change, we could use the same command to recompile:
% g++ -o main main.cpp Point.cpp Rectangle.cpp
But wait! This is wasteful because nothing in
Point.cpp changed, only
Rectangle.cpp, so why
should we recompile those other files?!
What we should have been doing instead is to use separate compilation, i.e., compile source code to intermediate object files and then link them together.
First, recall that the program is made up of 5 source files:
main.cpp, a main program.
Point.h, header file for the Point class.
Point.cpp, implementation file for the Point class.
Rectangle.h, header file for the Rectangle class.
Rectangle.cpp, implementation file for the Rectangle class.
We want to compile each piece of the program separately and then link them together. This will allow us to only regenerate the parts of the program that are affected when we change some source code.
When we just compile source code (without linking it
together), it means that we take the
.cpp files and generate
intermediate object files (
To just compile source code, use the
with the compiler...
% g++ -c main.cpp % g++ -c Point.cpp % g++ -c Rectangle.cpp
This will generate the object files:
List your files to see the intermediate object
Finally, to link the object files (
.o) into an executable
that we can run, we use the compiler again (although this time it will
just pass the
.o files on to the linking stage):
% g++ -o main main.o Point.o Rectangle.o
Since we have just compiled the executable
separately on the commandline, we know exactly what commands
are needed to generate the pieces that make up the executable.
Now, let's ask what we need to recompile (or relink) after we change certain files that make up our program...
For example, suppose we change the file
main.cpp...What has to be regenerated?
Answer: First, recompile
main.cpp to get
main.o. Then, relink all the object files together
again to get the executable
Now, suppose we changed
.cppfile changes or a header file included (directly or indirectly) by that
.cppfile changes, we have to regenerate its corresponding
For example, since
Rectangle.cpp indirectly includes
Rectangle.h, which itself includes
Rectangle.o must be
Since it is tedious to recompile pieces of a program when something changes, people often use the make utility to do it for them.
The make utility requires that you have a make file that tells it how to compile/link the program.
A make file should be named either Makefile (first letter uppercase) or makefile (all lowercase). The make file should be in the same directory as the source code files.
Remember, we already gave you a file called
Try using make (with the
Makefile you downloaded
earlier). First, remove the old executable and object files:
Then, run make with the command:% rm main *.o
Since nothing has been compiled/linked, it will do:
% g++ -c -o main.o main.cpp % g++ -c -o Point.o Point.cpp % g++ -c -o Rectangle.o Rectangle.cpp % g++ -o main main.o Point.o Rectangle.o
-oflags it uses with the first 3 g++ commands just make it explicit what the object file names will be. If you have trouble, make sure that the make file is named Makefile and is in the same directory as the source code files.
Note that it compiled the 3
.cpp files into object files,
and then linked the object files into an executable named
Now, type the make command again (let's explicitly tell it what to generate this time) and you get:
% make main make: `main' is up to date.
Here, make tells you nothing has changed, so it has no work to do.
Next, suppose we want the
area() method in the Rectangle
class to use the
Go ahead and edit the
area() method in
Rectangle.cpp now. Make sure you save the editted
file to disk.
After editing, when we use make:
% make g++ -c -o Rectangle.o Rectangle.cpp g++ -o main main.o Point.o Rectangle.o
it doesn't bother regenerating
since the files those depend on have not changed.