Using a Header File¶
The follow is a simple example of how to use a header (.h
) file. Note that
the file Intvec_main.cpp
is where the main
function, and testing code,
resides. It also``#include``s Intvec.h
at the top.
Intvec.h¶
// Intvec.h
#include "cmpt_error.h"
#include <iostream>
#include <cmath>
using namespace std;
class Intvec {
private:
int* arr; // pointer to the underlying array
int cap; // capacity of the underlying array, i.e. its size
int sz; // number of elements in the array
// doubles the capacity of the underlying array
void resizeArray() {
cap = 2 * cap;
// make the new array
int* newArr = new int[cap];
// copy elements into the new array
for(int i = 0; i < sz; ++i) {
newArr[i] = arr[i];
}
// delete the old array
delete[] arr;
// set up the new array
arr = newArr;
}
// Every element from arr[sz-1] to arr[start] is moved one position to the
// left. The value at arr[start] is over-written.
void shift_left(int start) {
for(int i = start; i < sz - 1; i++) {
arr[i] = arr[i + 1];
}
}
// Every element from arr[start] to arr[sz-1] is moved one position to the
// right. arr must have at least one extra space at the end.
void shift_right(int start) {
if (start >= sz) return;
for(int i = sz; i >= start; i--) {
arr[i] = arr[i - 1];
}
}
public:
// Default constructor that creates an empty array of size 0.
// The initial capacity of 10 is just a guess.
Intvec()
: cap(10), sz(0)
{
arr = new int[cap];
}
Intvec(const Intvec& other) {
sz = other.sz;
cap = other.cap;
arr = new int[other.cap];
for(int i = 0; i < other.sz; ++i) {
arr[i] = other.arr[i];
}
}
// This destructor is called automatically when an Intvec is deleted or
// leaves scope.
~Intvec() {
delete[] arr; // note the use of []
}
// Some of the following functions have "const" before their bodies. This
// indicates that the function does not modify the object. In other words,
// using "const" like this makes the function read-only.
bool empty() const {
return sz == 0;
}
int size() const {
return sz;
}
int capacity() const {
return cap;
}
int get(int i) const {
if (i < 0 || i >= sz) cmpt::error("get: index out of bounds");
return arr[i];
}
void set(int i, int x) {
if (i < 0 || i >= sz) cmpt::error("set: index out of bounds");
arr[i] = x;
}
// Add x to the end of this Intvec, re-sizing the underlying array if
// necessary.
void append(int x) {
if (sz >= cap) {
resizeArray();
}
arr[sz] = x;
sz++;
}
// Insert value x at location i.
void insert(int x, int i) {
// First check that i is a legal insertion index, i.e. 0 <= i <= sz.
if (i < 0 || i > sz) {
cmpt::error("insert: index i out of bounds");
}
// If necessary, re-size the underlying array.
if (sz >= cap) {
resizeArray();
}
// Make a new space for x at location i by shifting all the elements
// from arr[i] to arr[sz-1] one location to the right.
shift_right(i);
// Insert x into location i, and increase the size.
arr[i] = x;
sz++;
}
// Does the same thing as append, but implemented differently.
void insert_back(int x) {
insert(x, sz);
}
// Puts x at the front of the Intvec, moving all the other elements one
// position to the right.
void insert_front(int x) {
insert(x, 0);
}
// Removes (and returns) the item at location i. All items from arr[i+1]
// to arr[sz-1] are moved one position to the left, and the size is
// decreased by 1.
int remove(int i) {
// First check that i is a legal insertion index, i.e. 0 <= i < sz.
if (i < 0 || i >= sz) {
cmpt::error("insert: index i out of bounds");
}
// Save a copy of the value being removed.
int result = arr[i];
// Move all items from arr[i] to arr[sz-1] one position to the left,
// thus over-writing arr[i].
shift_left(i);
sz--;
return result;
}
int remove_back() {
return remove(sz - 1);
}
int remove_front() {
return remove(0);
}
void print() const {
cout << "[";
for(int i = 0; i < sz; ++i) {
cout << arr[i] << " ";
}
cout << "]";
}
void println() const {
print();
cout << "\n";
}
}; // class Intvec
Intvec_main.cpp¶
// Intvec_main.cpp
#include "Intvec.h"
#include "cmpt_error.h"
#include <iostream>
#include <cassert>
using namespace std;
void test1() {
Intvec v;
assert(v.size() == 0);
assert(v.empty());
for(int i = 1; i <= 1000; ++i) {
v.append(i);
double usage = 100 * v.size() / double(v.capacity());
int unused_bytes = sizeof(int) * (v.capacity() - v.size());
cout << v.size() << " " << v.capacity() << " " << usage << "% "
<< unused_bytes << " bytes unused\n";
}
}
void test2() {
Intvec v;
for(int i = 1; i <= 20; ++i) {
v.append(i);
}
v.println();
v.insert(-1, 0);
v.println();
v.insert(-2, 10);
v.println();
v.insert(-3, v.size());
v.println();
}
void test3() {
Intvec v;
for(int i = 1; i <= 21; ++i) {
v.insert_back(i);
// v.insert_front(i);
// v.println();
}
cout << v.size() << " " << v.capacity() << "\n";
}
void test4() {
for(int i = 0; i < 10; ++i) {
test3();
}
}
void test5() {
Intvec v;
for(int i = 1; i <= 20; ++i) {
v.insert_back(i);
}
v.println();
v.remove(0);
v.println();
v.remove(10);
v.println();
v.remove(v.size() - 1);
v.println();
}
void test6() {
Intvec v;
for(int i = 1; i <= 20; ++i) {
v.insert_back(i);
}
while (!v.empty()) {
v.println();
v.remove_front();
}
v.println();
}
void test7() {
Intvec v;
for(int i = 1; i <= 20; ++i) {
v.insert_back(i);
}
while (!v.empty()) {
v.println();
v.remove_back();
}
v.println();
}
int main() {
// test1();
// test2();
// test3();
// test4();
// test5();
// test6();
test7();
}