C + + provides a number of powerful mechanisms to achieve high code reuse, so that we can use our own classes as quickly and easily as with built-in types. such as templates, operator overloading, and so on. Templates such as a large production of functions and classes of the factory, so that we do not have to care about the data types related to the tedious programming details, put our energies to those who really deserve our serious thinking about the place. Operator overloading makes our programs more intuitive and concise, which not only makes it easier for us to read our programs, but also allows us to express our ideas in a more fluid way. As mentioned in the previous article, if we implement a dynamically allocated two-dimensional array with a class template and overload the corresponding operator, we can easily use the array type we have defined ourselves. Today, I just sorted out the previous procedures and posted them together to see the following procedure. The following two class templates compile well on vc++6.0, the test program also get the correct results, if there are any problems in other compilation environment, please leave a message.
The first header file Array.h is a one-dimensional dynamic array class template:
Array.h
#ifndef Carl_sen_array_h
#define Carl_sen_array_h
#include <iostream>
#include <cstdarg>
Using Std::out_of_range;
Using Std::ostream;
Template<typename t>
Class Array {
Protected
unsigned int size;
t* data;
Public
Constructors
Array (unsigned int _size=0);
Array (unsigned int count, T data1, ...);
Replication control
Array (const array<t>& array);
array& operator= (const array<t>& Array);
~array () {
delete[] data;
}
Two overloaded operators
t& operator[] (unsigned int index);
Const t& operator[] (unsigned int index) const;
Friend ostream& operator<< (ostream& os, const array<t>& Array);
Get,set member functions
unsigned int getsize () const {
return size;
}
void setSize (unsigned int newsize);
};
Template <typename t>
Array<t>::array (unsigned int _size):d ata (new t[_size)), size (_size) {
for (unsigned int i=0; i<size; ++i) {
Data[i]=t ();
}
}
Template <typename t>
Array<t>::array (unsigned int count, T data1, ...): Size (count), data (new T[count]) {
Va_list ap;
Va_start (AP, Count);
for (unsigned int i=0; i<size; ++i) {
Data[i]=va_arg (AP, T);
}
Va_end (AP);
}
Template <typename t>
Array<t>::array (const array<t>& Array): Size (array.size), data (new T[array.size]) {
for (unsigned int i=0; i<size; ++i) {
Data[i]=array.data[i];
}
}
Template <typename t>
array<t>& array<t>::operator= (const array<t>& Array) {
if (&array!=this) {
delete[] data;
Data=new T[array.size];
Size=array.size;
for (unsigned int i=0; i<size; ++i) {
Data[i]=array.data[i];
}
}
return *this;
}
Template <typename t>
t& array<t>::operator[] (unsigned int index) {
if (index>=size) {
Throw Out_of_range ("Invalid index");
}
return Data[index];
}
Template <typename t>
Const t& array<t>::operator[] (unsigned int index) const {
if (index>=size) {
Throw Out_of_range ("Invalid index");
}
return Data[index];
}
Template <typename t>
void array<t>::setsize (unsigned int newsize) {
t* const newdata=new T[newsize];
const unsigned int min=size<newsize?size:newsize;
for (unsigned int i=0; i<min; ++i) {
Newdata[i]=data[i];
}
delete[] data;
Data=newdata;
Size=newsize;
}
Template <typename t>
ostream& operator<< (ostream& os, const array<t>& Array) {
for (int i=0; i<array.size; ++i) {
os<<array.data[i]<< "T";
}
return OS;
}
#endif
The second head file Array2D.h is a two-dimensional dynamic array class template:
Array2D.h
#ifndef Carl_sen_array2d_h
#define Carl_sen_array2d_h
#include "Array.h"
#include <iostream>
#include <cstdarg>
Using Std::ostream;
Using Std::out_of_range;
Template <typename t>
Class Array2D {
Protected
unsigned int rows;
unsigned int cols;
Array<t> Array;
Public
Constructors
Array2D (unsigned int _rows=0, unsigned int _cols=0);
Array2D (unsigned int _rows, unsigned int _cols, T data1, ...);
Two overloaded operators
Class Rowarray;
Rowarray operator[] (unsigned int row);
Const Rowarray operator[] (unsigned int row) const;
Friend ostream& operator<< (ostream& os, const array2d<t>& array2d);
Nested class to compute the second dimension subscript operation
Class Rowarray {
Private
Const array2d<t>& Array2D;
unsigned int row;
Public
Rowarray (array2d<t>& _array2d, unsigned int _row=0):
Array2D (_array2d), row (_row) {}
Rowarray (const array2d<t>& _array2d, unsigned int _row=0):
Array2D (_array2d), row (_row) {}
t& operator[] (unsigned int col) {
if (col>=array2d.cols) {
Throw Out_of_range ("invalid col");
}
Return const_cast<array2d<t>&> (Array2D). Array[row*array2d.cols+col];
}
Const t& operator[] (unsigned int col) const {
if (col>=array2d.cols) {
Throw Out_of_range ("invalid col");
}
return Array2d.array[row*array2d.cols+col];
}
};
Friend class Rowarray;
Get,set function
unsigned int getRows () const {
return rows;
}
unsigned int getcols () const {
return cols;
}
};
Template <typename t>
array2d<t>::array2d (unsigned int _rows, unsigned int _cols):
Rows (_rows), cols (_cols), array (_rows*_cols) {
for (unsigned int i=0; i<rows*cols; ++i) {
Array[i]=t ();
}
}
Template <typename t>
array2d<t>::array2d (unsigned int _rows, unsigned int _cols, T data1, ...):
Rows (_rows), cols (_cols), array (_rows*_cols) {
Va_list ap;
Va_start (AP, _cols);
for (unsigned int i=0; i<rows*cols; ++i) {
Array[i]=va_arg (AP, T);
}
Va_end (AP);
}
Template <typename t>
Array2d<t>::rowarray array2d<t>::operator[] (unsigned int row) {
if (row>=rows) {
Throw Out_of_range ("Invalid Row");
}
Return Rowarray (*this, Row);
}
Template <typename t>
Const Array2d<t>::rowarray array2d<t>::operator[] (unsigned int row) const {
if (row>=rows) {
Throw Out_of_range ("Invalid Row");
}
Return Rowarray (*this, Row);
}
Template <typename t>
ostream& operator<< (ostream& os, const array2d<t>& array2d) {
unsigned int i, J;
For (i=0 i<array2d.rows; ++i) {
For (j=0 j<array2d.cols; ++j) {
os<<array2d.array[i*array2d.cols+j]<< "T";
}
if (i!=array2d.rows-1) {
os<<endl;
}
}
return OS;
}
#endif
You can now use them, as in the following test program:
#include "Array.h"
#include "Array2D.h"
#include <iostream>
#include <string>
Using Std::string;
Using Std::cout;
Using Std::endl;
void Testarray ();
void Testarray2d ();
int main () {
Testarray ();
Testarray2d ();
return exit_success;
}
void Testarray () {
Normal array
Array<int> A1 (3);
cout<< "Testing Array:print 1" <<endl;
cout<<a1<<endl; Overall printing
unsigned int i;
for (i=0; I<a1.getsize (); ++i) {
a1[i]=i+1; Assign values one by one
}
cout<< "Testing Array:print 2" <<endl;
for (i=0; I<a1.getsize (); ++i) {
cout<<a1[i]<< "T"; Print one by one
}
cout<<endl;
Constants Array
Const Array<int> A2 (3, 123, 234, 345);
cout<< "Testing Array:print 3" <<endl;
cout<<a2<<endl;
cout<< "Testing Array:print 4" <<endl;
for (i=0; I<a2.getsize (); ++i) {
cout<<a2[i]<< "T";
}
cout<<endl;
Copy Construction
Array<int> A3 (A1);
cout<< "Testing Array:print 5" <<endl;
cout<<a3<<endl;
Const array<int> A4 (A2);
cout<< "Testing Array:print 6" <<endl;
cout<<a4<<endl;
Array assignment to array
Array<int> A5;
A5=A4;
cout<< "Testing Array:print 7" <<endl;
cout<<a5<<endl;
Add or subtract array elements
A5.setsize (A5.getsize () +1);
A5[a5.getsize () -1]=111;
cout<< "Testing Array:print 8" <<endl;
cout<<a5<<endl;
A5.setsize (A5.getsize ()-2);
cout<< "Testing Array:print 9" <<endl;
cout<<a5<<endl;
Save Object
Array<string> A6 (2, String ("Str0"), String ("str1"));
cout<< "Testing Array:print" <<endl;
cout<<a6<<endl;
for (i=0; I<a6.getsize (); ++i) {
A6[i]+=static_cast<char> (48+i);
}
cout<< "Testing Array:print" <<endl;
for (i=0; I<a6.getsize (); ++i) {
cout<<a6[i]<< "T";
}
cout<<endl;
Const array<string> A7 (3, String ("V"), String ("a"), String ("222"));
cout<< "Testing Array:print" <<endl;
cout<<a7<<endl;
for (i=0; I<a7.getsize (); ++i) {
cout<<a7[i]<< "T";
}
cout<<endl;
}
void Testarray2d () {
Normal array
Array2d<int> A1 (2, 2);
cout<< "Testing Array2d:print 1" <<endl;
cout<<a1<<endl;
unsigned int i,j;
for (i=0; I<a1.getrows (); ++i) {
for (j=0; J<a1.getcols (); ++j) {
A1[i][j]=i+j;
}
}
cout<< "Testing Array2d:print 2" <<endl;
for (i=0; I<a1.getrows (); ++i) {
for (j=0; J<a1.getcols (); ++j) {
cout<<a1[i][j]<< "T";
}
cout<<endl;
}
Constants Array
Const Array2d<int> A2 (2, 2, 123, 234, 345, 456);
cout<< "Testing Array2d:print 3" <<endl;
cout<<a2<<endl;
cout<< "Testing Array2d:print 4" <<endl;
for (i=0; I<a2.getrows (); ++i) {
for (j=0; J<a2.getcols (); ++j) {
cout<<a2[i][j]<< "T";
}
cout<<endl;
}
Copy Construction
Array2d<int> A3 (A1);
cout<< "Testing Array2d:print 5" <<endl;
cout<<a3<<endl;
Const array2d<int> A4 (A2);
cout<< "Testing Array2d:print 6" <<endl;
cout<<a4<<endl;
Array assignment to array
Array2d<int> A5;
A5=A4;
cout<< "Testing Array2d:print 7" <<endl;
cout<<a5<<endl;
Save Object
Array2d<string> A6 (2, 2, String ("Str00"), String ("Str01"), String ("Str10"), String ("Str11"));
cout<< "Testing Array2d:print 8" <<endl;
cout<<a6<<endl;
for (i=0; I<a6.getrows (); ++i) {
for (j=0; J<a6.getcols (); ++j) {
A6[i][j]+=static_cast<char> (48+I+J);
}
}
cout<< "Testing Array2d:print 9" <<endl;
for (i=0; I<a6.getrows (); ++i) {
for (j=0; J<a6.getcols (); ++j) {
cout<<a6[i][j]<< "T";
}
cout<<endl;
}
Const array2d<string> A7 (2, 1, String ("11111"), String ("22222"));
cout<< "Testing Array2d:print" <<endl;
cout<<a7<<endl;
cout<< "Testing Array2d:print" <<endl;
for (i=0; I<a7.getrows (); ++i) {
for (j=0; J<a7.getcols (); ++j) {
cout<<a7[i][j]<< "T";
}
cout<<endl;
}
}