This lesson is still being designed and assembled (Pre-Alpha version)

Headers and Interfaces

Overview

Teaching: 10 min
Exercises: 0 min
Questions
  • What is an interface?

  • Why separate some of the code into header files?

Objectives
  • Understand the difference between header and implementation files

  • Comprehend code using preprocessor directives

Headers and Interfaces

An interface describes functionality without providing any implementation. An interface is defined in a header file, which has a different extension (usually .hpp or just .h) than the implementation file (which will usually be .cpp or .cc).

In a header file hello.hpp, you may see a function declaration with no implementation such as:

void printHello();

And then used in another file myfile.cpp:

#include "hello.hpp"
int main() {
    printHello();
}

But how does the computer know what to execute when it gets to the printHello() statement? When we compile, we must include an implementation file (or link against a library) that implements the function.

But why do we do this? Why not just keep all the code in one file? There are several answers to this question, but here are a few of them:

Preprocessor Directives

Preprocessor directives use the # character. These lines are not statements, and thus do not need a semicolon to terminate the line. Rather, they are terminated by a newline character, similar to single line comments // like this.

// file inclusion
#include "hello.cpp"

// macro defines a constant
#define MY_GOLDEN_NUMBER 1746

// compile time decision
#ifdef USE64BITS
typedef uint64_t myint;
#else
typedef uint32_t myint;
#endif

The #define directive will effectively replace all instances of the token MY_GOLDEN_NUMBER with 1746 before compiling. The #ifdef, #else and #endif allow the compiler to check whether the identifier USE64BITS is defined and conditionally declare a typedef depending on the desired size of an integer in this architecture.

Preprocessor directives are used in only restricted cases, namely

You might also see preprocessor directives in header files to prevent the compiler from reading a header file twice and compilaing that the function printHello is declared twice, as in this example:

#ifndef PRINT_HELLO_HPP
#define PRINT_HELLO_HPP

void printHello();

#endif

This uses directives to define the PRINT_HELLO_HPP identifier only once and prevent passing the header file to the compiler twice if it is included by many files in a large code project.

Key Points

  • Preprocessor directives are useful for making compile-time decisions

  • By separating header files and implementation files we can program to interfaces, not implementations.