A functional Array Class
A functional pre-templatised implementation of an array class.
For the finished version see here.
This approach makes substantial use of overloaded operators.
I have also used the STL exception handling classes.
They offer a standardised and extensible approach to exception handling
which I think will become the norm.
| Header |
#ifndef _Array_h_
#define _Array_h_
// INCLUDES
//
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdexcept>
// NAME: Array.H
// TYPE: C++ CLASS
//
// SYNOPSIS: Data type is typedefed as type data_type
// prior to possible implementation as a
// template class
// DESCRIPTION: Interface for array class
// EXAMPLES: See Driver
// BUGS:
// SEE ALSO:
////////////////////////////////////////////
using namespace std;
typedef char data_type;
|
|
class Array
{
public:
// LIFECYCLE
Array(int arraySize=10); // constructor`
Array(const Array&); // copy constructor
~Array(); // destructor
// OPERATORS
friend ostream& operator<<(ostream&
, const Array&);
friend istream& operator>>(istream&
, Array&);
const Array& operator=(const
Array&);
bool operator==(const Array&)
const;
bool operator!=(const Array&)
const;
data_type& operator[](int);
// OPERATIONS
// ACCESS
int Size() const; // return
size
static int Count(); // return #
of Arrays instantiated
// INQUIRY
// DATA
private:
data_type *p; // points to first element of array
int sz; // size of array
static int arrays; // # of arrays
};
#endif // _Array_h_
|
|
Note that I have used a typedef data_type to represent the data.
This ensures it is a simple matter to replace the correct
instances the data in the code when converting to a template
|
|
|
| class Array |
// INCLUDES
#include"Array.h"
// NAME: Array.CPP
// TYPE: C++ SOURCE
// SYNOPSIS:
// Exception handling based on the STL exception class
// Constness extended
// DESCRIPTION: Implementation and Driver for Array class
// EXAMPLES:
// BUGS:
// SEE ALSO:
///////////////////////////////////////X/////
// Initialise static data member at file scope
int Array::arrays =0;
|
|
// Return # of array objects
int
Array::Count(){ return arrays;}
// Default constructor
Array::Array(int size)
{
++arrays;
sz = size; // default size is 10
p = new data_type[sz]; // create space for array
if(!p) throw runtime_error("out of memory");
}
// Copy constructor
Array::Array(const Array& init)
{
++arrays;
sz = init.sz;
p = new data_type[sz]; // create new p
if(!p) throw runtime_error("out of memory");
for(int i =0; i<sz; i++) // copy init data
p[i] = init.p[i];
}
// Destructor
Array::~Array()
{
--arrays;
delete[]p;
}
// Get size of array
int
Array::Size() const{ return sz;}
// Overload subscript operator
data_type&
Array::operator[](int subscript)
{
// check for subscript out of range error
if(subscript < 0 || subscript > sz)
throw range_error("subscript out of range");
return p[subscript]; // reference return creates
lvalue
}
bool
Array::operator==(const Array&
a) const
{
if(sz != a.sz)
return false; // different size
for(int i=0; i <sz; i++)
if(p[i] != a.p[i])
return false; // not equal
return true; // equal
}
// true if != else false
bool
Array::operator !=(const Array
&a) const
{
if (sz != a.sz) // different size
return true;
for( int i =0; i<sz; i++)
if(p[i] != a.p[i])
return true; // not equal
return false; // equal
}
// Overloaded assignment operator
const Array&
Array::operator=(const Array&
a)
{
if(&a != this) // check for
self assignment
{
delete [] p;
sz = a.sz;
p = new data_type[sz]; // create space for array
copy
if(!p) throw runtime_error("out
of memory");
for(int i=0; i<sz; i++) //
copy array into object
p[i] =a.p[i];
}
return *this; // enables x = y = z
}
// Overloaded input operator for class Array
// inputs values for entire array
istream&
operator>>(istream& input, Array&
a)
{
for(int i=0; i <a.sz; i++)
input>>a.p[i];
return input; // enables cin >> x >>
y
}
// Overloaded << operator
ostream&
operator<<(ostream& output, const
Array& a)
{
int i;
for(i=0; i <a.sz; i++)
{
output<<a.p[i] << ' ';
}
output<<endl;
return output; // enables cout << x
<< y
}
|
|
Note:
|
|
|
|
Driver
|
|
void main()
{
// two static Arrays
Array array1, array2;
try{
// test Array.Count()
cout<<"\nThere are now "<<array1.Count()<<"
Array objects";
// test overloaded >>
cout<<"\n\nEnter array1 data\n";
cin>>array1;
// test overloaded <<
cout<<"\narray1 data : "<<array1;
// test overloaded []
for(int i=0; i<array1.Size();
i++)
array2[9-i]=array1[i];
cout<<"\narray2 data : "<<array2;
// test overloaded == and !=
cout<<"\narray1 is ";
if(array1==array2)
cout<<"equal";
if(array1!=array2)
cout<<"not equal";
cout<<" to array2\n";
// test copy constructor
Array array3(array1);
cout<<"\nThere are now "<<array1.Count()<<"
Array objects";
cout<<"\narray3 data : "<<array3;
cout<<"\n\narray1 is ";
if(array1==array3)
cout<<"equal";
if(array1!=array3)
cout<<"not equal";
cout<<" to array3\n";
// array1[22] = 'a'; // throws an out_of_range exception
array1=array2=array3;
// test overloaded == and !=
cout<<"\narray1 is ";
if(array1==array2)
cout<<"equal";
if(array1!=array2)
cout<<"not equal";
cout<<" to array2\n";
cout<<"\n\nPress any key to exit...";
}//try
catch (const exception& e)
{
cout << "\n\nException: " << e.what()
<< endl;
}
};
|
| Note: |
|
|
|
|