Classes are great for organizing your code, and for making it more portable. A well-written class is package of code that solves some problem. For example, strings and vectors are both classes. Let's ignore strings and just talk about vectors for a bit. The job of a vector is to store a bunch of data, as well as give us options to access and manipulate our data.

vector<int> vec = {1,5,2,5,8,3,7,9};

This object vec is called an instance of the class vector. It is also called an object of type vector. Right now vec is holding 8 integers worth of data. It also keeps track of some other useful pieces of information, such as the size of the vector.

In addition to the data stored, vec also comes equipped with some useful functions. Some examples are:

The idea here is that by writing the one line of code

vector<int> vec = {1,5,2,5,8,3,7,9};

we've created a complicated object that both stores some raw data and also gives us a lot of ways to manipulate it. We'll learn to write our own classes with this in mind.

Example Class: BankAccount

Here's the problem setup: You run your own bank. You are in charge of 50 bank accounts, and you need to write code that will keep track of the different balances (which includes letting you deposit, withdraw, or view your balance). You all could probably solve this problem without classes, but I think it will look a lot better if we build a class. We're going to call our class BankAccount, and here is the rough setup:

Each object of type BankAccount will store 1 piece of data (the current account balance). It will also have functions that allow you to view the balance, to withdraw money from the account, and to deposit money into the account.

We'll build this up piece by piece in class. Here's the final code.


Constructor Functions

For all the variable types we've seen so far, we can both define and initialize a variable at the same time. For example:

int x = 0;  // Says that x is a variable of type int. Sets the value of x to 0.
string str = "Hello"; // Says that str is a variable of type string. Sets the value of str to "Hello".

We can mimic that behavior in the classes we write by adding in a special type of member function. These are called constructor functions. Here's an example using vectors:

  vector<int> vec; // Creates an empty vector.
  vector<int> vec2(100);  // Creates a vector of size 100

We're going to write some code that will let us do similar things with our BankAccount class. Here's the finished version:


Header Files

With the constructors written, we've done everything I wanted to do with the BankAccount class. At this point we could really easily create 50 BankAccount via:

vector<BankAccount> vectorFullOfBankAccounts(50);

Then if, for example, we wanted to add $50 to the account at position 7, we could write:


The next thing I want to do is to put this code into a Header File. Here's the setup: if I want to use vectors, then I just #include<vector>. If I want to use strings, then I #include<string>. Now we've created this BankAccount class that is supposed to handle all your bank-account-related problems, but it isn't very portable. If I want to use BankAccount, I have to copy-paste the whole thing. Bleh. By creating a header file, we can #include our BankAccount just as easily as anything else.

Here are the finished files.


Separating Declarations and Definitions

Okay, we're going to make one last change. This will make your code compile faster (i.e. when you press "Build" it won't take as long). This particular project is pretty small so we probably won't notice a difference, but in big projects this can make a real difference.

So. When you compile your code, it has to compile the header files (the .h files) every time. However, it only compiles the source files (the .cpp files) if you have made a change. So the idea is to put as much code as possible into .cpp file, and keep the header files pretty bare-bones. Here's the example with BankAccount (and the last version of this code!).