C++ Notes: Multiple Source Files

Small programs are typically written in a single .cpp file. However, as programs get larger, it's necessary to split the source into several files in order to make the project manageable.

Use .h files to for shared declarations

Because C++ needs to know the declarations of functions before they are called, function prototypes (declarations) are typically written at the top of a single-file, multiple-function program. This ensures that the call and the definition are both consistent.

Similarly, when using muliple source files, you want to use the same declaration where the function is called as where it's defined. The solution is to create a header file (.h) which contains the function declarations. By #including this in all source files (.cpp) that use or define this function, consistency is maintained.

Project?

If you user an IDE (eg, instead of a make file), you often have to create a project and add all source files to it, so that it knows which files belong together. A project may also include other, non-source, resource files.

Example with two source files and a shared header

Here's a example, with the main program in one file, a function in another, and a header file containing the function prototype. This is a common pattern, alto the header file may contain definitions without a corresponding .cpp file.

Header file - average.h

  1 
  2 
  3 
// multiple-files/average.h - Function prototype.
 
float average(const vector<float>& x);

Main program - averageMain.cpp

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
// muliple-files/averageMain.cpp -- Print above average numbers.
//      Illustrates multiple source file compilations.
// Fred Swartz -- 2004-11-17

//... Standard includes
#include <iostream>
#include <stdlib.h>
#include <vector>
using namespace std;

//... Private include for average function.
#include "average.h"

//=========================================================== main
int main(){
    
    vector<float> fv;    // Store the input floats here.
    float         temp;  // Temp for input.
    
    //... Read floats into vector
    while (cin >> temp) {
        fv.push_back(temp);
    }   
    
    //... Compute average.
    float avg = average(fv); 
  
    //... Print greater than average numbers.
    cout << "Average = " << avg << endl;
    for (int i = 0; i < fv.size(); i++) {
        if (fv[i] > avg) {
            cout << fv[i] << endl;
        }
    }      
	
    return 0;
}

Function definition - average.cpp

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
// multiple-files/average.cpp -- Compute average in vector.
//         It would be nicer to make this a template function.
// Fred Swartz -- 2004-11-17

//... Standard includes
#include <vector>
using namespace std;

//... Private header file with prototype for average.
#include "average.h"

//======================================================== average
float average(const vector<float>& x) {
    float sum = 0.0;
    for (int i=0; i<x.size(); i++) {
        sum += x[i];
    }    
    
    return sum / x.size();
}