We
can now modify earlier examples to use function overloading. As stated before,
an immediately useful place for overloading is in constructors. You can see
this in the following version of the
Stash
class:
//: C07:Stash3.h
// Function overloading
#ifndef STASH3_H
#define STASH3_H
class Stash {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
// Dynamically allocated array of bytes:
unsigned char* storage;
void inflate(int increase);
public:
Stash(int size); // Zero quantity
Stash(int size, int initQuant);
~Stash();
int add(void* element);
void* fetch(int index);
int count();
};
#endif
// STASH3_H ///:~
The
first
Stash( )
constructor is the same as before, but the second one has a
Quantity
argument to indicate the initial number of storage places to be allocated. In
the definition, you can see that the internal value of
quantity
is set to zero, along with the
storage
pointer. In the second constructor, the call to
inflate(initQuant)
increases
quantity
to the allocated size:
//: C07:Stash3.cpp {O}
// Function overloading
#include "Stash3.h"
#include <iostream>
#include <cassert>
using namespace std;
const int increment = 100;
Stash::Stash(int sz) {
size = sz;
quantity = 0;
next = 0;
storage = 0;
}
Stash::Stash(int sz, int initQuant) {
size = sz;
quantity = 0;
next = 0;
storage = 0;
inflate(initQuant);
}
Stash::~Stash() {
if(storage != 0) {
cout << "freeing storage" << endl;
delete []storage;
}
}
int Stash::add(void* element) {
if(next >= quantity) // Enough space left?
inflate(increment);
// Copy element into storage,
// starting at next empty space:
int startBytes = next * size;
unsigned char* e = (unsigned char*)element;
for(int i = 0; i < size; i++)
storage[startBytes + i] = e[i];
next++;
return(next - 1); // Index number
}
void* Stash::fetch(int index) {
assert(0 <= index && index < next);
// Produce pointer to desired element:
return &(storage[index * size]);
}
int Stash::count() {
return next; // Number of elements in CStash
}
void Stash::inflate(int increase) {
assert(increase > 0);
int newQuantity = quantity + increase;
int newBytes = newQuantity * size;
int oldBytes = quantity * size;
unsigned char* b = new unsigned char[newBytes];
for(int i = 0; i < oldBytes; i++)
b[i] = storage[i]; // Copy old to new
delete [](storage); // Release old storage
storage = b; // Point to new memory
quantity = newQuantity; // Adjust the size
}
///:~
When
you use the first constructor no memory is allocated for
storage.
The allocation happens the first time you try to
add( )
an object and any time the current block of memory is exceeded inside
add( ).
Both
constructors are exercised in the test program:
The
constructor call for
stringStash
uses
a second argument; presumably you know something special about the specific
problem you’re solving that allows you to choose an initial size for the
Stash.