Skip to main content

Section 16.11 Using Headers

There are reasons both technical and practical to break classes up into separate files.
Most importantly, the compiler requires access to function declarations everywhere those functions are used. But we don’t want to compile the definitions of functions multiple times. So we generally want to place the class declaration in a .h file with just the function declarations and leave the function definitions for a .cpp file.
This system also works to turn .h files into the β€œinterface” for a class. Programmers working on client code should only care about what functions there are, not how they are implemented. By putting the class with just the function declarations (and comments!) into a .h file and keeping the implementations in a .cpp file, it helps enforce the design goal of information hiding.

Aside

The process for splitting a class into a .h/.cpp file pair is similar to doing so for a standard function. The .h file contains the class with all the function declarations while the .cpp file contains the implementation of the member functions. Typically, we put each class in a separate file and name the files to match the name of the class they contain. So out Point class should go in Point.h and Point.cpp.
Listing 16.11.1. Point.h
// Header guard
#ifndef SIMPLE_POINT_H
#define SIMPLE_POINT_H

// Include any libraries that are referenced here in the .h
// such as <string>

/**
 * @brief Represents a point in 2D space.
 * 
 */
class Point {
public:
    /**
     * @brief Construct a new Point object
     * 
     * @param x starting x coordinate
     * @param y starting y coordinate
     */
    Point(double x, double y);

    /**
     * @brief Get the x coordinate of the point
     * 
     * @return double x coordinate
     */
    double getX();
private:
    double m_x;
    double m_y;
};

#endif // SIMPLE_POINT_H

Note 16.11.1.

In a perfect world, it might be nice to only list the public members in the .h file. But the .h file needs to have the complete class declaration minus the function definitions.
When writing the .cpp file, we need to remember to use the scope resolution operator to specify that member functions are a part of the class. We include the .h file so that the compiler knows what that class looks like.
Listing 16.11.2. Point.cpp
// Include <cmath> or any other needed libraries

// Include the header file for the Point class
#include "Point.h"

// possibly use using namespace std;

Point::Point(double x, double y) {
  m_x = x;
  m_y = y;
}

double Point::getX() {
  return m_x;
}
Then to use the Point class, other code can simply include the .h file and be compiled along with the .cpp file:
Listing 16.11.3.
$ g++ Point.cpp main.cpp -o program.exe

Checkpoint 16.11.1.

What statements are true based on the following Student.h header file?
class Student {
public:
  Student(int age, int id, string year);
  Student(string year);
  void increment(int age);
  void print();
  bool isJunior();
private:
  // Instance variables
  int m_age, m_id;
  string m_year;
};
  • The Student.cpp file will have void Student::print() {...}.
  • This is true!
  • Student.cpp needs to #include the header file.
  • This is true!
  • The Student.cpp file must implement the constructors before the isJunior function.
  • This is not necessary. Because they have all been declared, the order of the function implementations does not matter.
  • The .cpp file will need to define Student::m_age = 0;
  • The .cpp file will only have function definitions. The instance variables are only listed in the class declaration in the .h.
You have attempted of activities on this page.