<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Population</title>
</head>

<body>



<p align="left"><font size="6" color="#FF0000"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Array exception</b></font></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A.<span lang="en-ca"> </span>First Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is second<span lang="en-ca"> edition of </span>my simple assignment which requires you to write both template and exception handling.</b></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<div align="left">
  <b>How to use template for re-usage and exception handling mechnism?</b></div>
<div align="left">
  　</div>
<div align="left">
  　</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca">C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  <pre><b>What should I say about this?</b></pre>
</div>
<div align="left">
  <pre><b><font size="5" color="#FF0000">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="5" color="#FF0000"><b>E</b></font></span><b><font color="#ff0000" size="5">.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre><b>1.<span lang="en-ca"> </span>I should write one more user-defined class object for testing.</b></pre>
</div>
<pre>　</pre>
<pre><b><font color="#FF0000" size="3">//file Array.h</font></b></pre>
<pre>///////////////////////////////////
// Date: August 10, 2003
// Author: C. Taillefer
// File: Array.h
///////////////////////////////////
// Array Header File with patial
// implementation.
///////////////////////////////////


#ifndef ARRAY_H
#define ARRAY_H

#include &lt;iostream&gt;

using namespace std;

#include &quot;exception.h&quot;

template &lt; class T &gt;
class Array 
{
   friend ostream &amp;operator&lt;&lt;( ostream &amp; output, const Array&lt;T&gt;&amp; a )
   {
		for ( int i = 0; i &lt; a.size; i++ ) 
		{
			output &lt;&lt; ' ' &lt;&lt; a.ptr[ i ];	
		}
		return output ; 
   }		
public:
   Array( int = 10 );                   // default constructor
   Array( const Array &amp; );              // copy constructor
   ~Array();                            // destructor
   int getSize() const;                 // return size
   T&amp; operator[]( int index ) ;
   bool operator==( const Array&amp; ) const ;
   const Array&amp; operator() ( int first, int last ) ;
private:
   int size; 				// size of the array
   T* ptr; 					// pointer to first element of array
};



//////////////////////////////////////////////////////////////////
// Default constructor for class Array (default size 10)
template &lt; class T &gt;
Array&lt; T &gt;::Array( int arraySize ) {
	if (arraySize &lt;= 0 ) { throw Error( &quot;Invalid Size&quot; ) ; }
	else {
		size = arraySize ; 
		ptr = new T[ size ]; // create space for array
		if ( ptr == 0 ) { throw Error( &quot;No Memory Allocation&quot; ) ; }    
	
		for ( int i = 0; i &lt; size; i++ )
			ptr[ i ] = 0;          // initialize array
	}
	
}


////////////////////////////////////////////////////////////////
// Copy constructor for class Array
// must receive a reference to prevent infinite recursion
template &lt; class T &gt;
Array&lt; T &gt;::Array( const Array &amp;init ) : size( init.size ) {
	ptr = new T[ size ]; // create space for array
	if ( ptr == 0 ) { throw Error( &quot;No Memory Allocation&quot; ) ; }  

	for ( int i = 0; i &lt; size; i++ )
		ptr[ i ] = init.ptr[ i ];  // copy init into object
}


////////////////////////////////////////////////////////////////
// Destructor for class Array
template &lt; class T &gt;
Array&lt; T &gt;::~Array() {
   delete [] ptr;            // reclaim space for array
}


////////////////////////////////////////////////////////////////
// Get the size of the array
template &lt; class T &gt;
int Array&lt; T &gt;::getSize() const { return size; }


////////////////////////////////////////////////////////////////
// Overloaded subscript operator for class Array 
template &lt; class T &gt;
T&amp; Array&lt; T &gt;::operator[]( int index ) {
	if (index &gt;= size ) { throw Error( &quot;Index Out of Bounds&quot; ) ; }
	return ptr[ index ] ;	
}



//if user pass a &quot;class T&quot;, say &quot;Student&quot; which is a user-defined class,
//then user must define operator overloading function:
// bool Student::operator==(Student&amp; S);
template&lt; class T &gt;
bool Array&lt;T&gt;::operator ==(const Array&lt;T&gt;&amp; other) const
{
	if (this==&amp;other)//test if this object
	{
		return true;
	}
	else
	{
		if (size==other.size)//size must be same
		{
			for (int i=0; i&lt;size; i++)
			{
				//I guess for a certain class &quot;T&quot;, user usually only defines &quot;==&quot;
				//instead of &quot;!=&quot;
				if (!(ptr[i]==other.ptr[i]))//should user define this by himself?
				{
					return false;
				}
			}
			return true;//this means all element is equal
		}
	}
	return false;
}
//return object itself with chopped off array
template&lt; class T &gt;
const Array&lt;T&gt;&amp; Array&lt;T&gt;::operator()(int first, int last)
{
	if (first&lt;0||last&lt;0)
	{
		throw Error(&quot;Negative subscript not allowed!&quot;);
	}
	if (last&lt;first)
	{
		throw Error(&quot;Last cannot be smaller than first!&quot;);
	}
	if (first&gt;=size||last&gt;=size)
	{
		throw Error(&quot;Index Out of Bounds&quot;);
	}
	if (first==0&amp;&amp;last==size-1)//this is a shortcut which returns original itself
	{
		return *this;
	}
	//use safe mode to backup old ptr and size, in case exception, try restore them
	T* oldPtr = ptr;
	int oldSize = size;
	size = last - first + 1;
	ptr = new T [size];
	if (ptr==NULL)
	{
		//before throw, restore old data first
		ptr= oldPtr;
		size = oldSize;
		throw Error(&quot;No Memory Allocation&quot;);
	}
	for (int i=0; i&lt;size; i++)
	{
		ptr[i] = oldPtr[first+i];
	}
	delete [] oldPtr;//delete old ptr

	return *this;
}

#endif
</pre>
<pre><b><font size="3" color="#FF0000">//file Exception.h</font></b></pre>
<pre>///////////////////////////////////
// Date: August 10, 2003
// Author: C. Taillefer
// File: exception.h
///////////////////////////////////
// Exception Object Header File 
// with implementation.
///////////////////////////////////

#ifndef EXCEPTION_H
#define EXCEPTION_H

#include &lt;cstring&gt;

class Error {
public:
	Error( char* msg = &quot;&quot; ) 
	{ message = new char[ strlen(msg)+1 ] ; strcpy( message, msg ) ; }
	Error( const Error&amp; err ) 
	{ message = new char[ strlen(err.message)+1 ] ; 
		strcpy( message, err.message ) ; }
	~Error() { delete [] message ; }
	const char* what() { return message ; }
private:
	char* message ;
} ;


#endif
</pre>
<pre>　</pre>
<pre><b><font size="3" color="#FF0000">//file Driver.cpp</font></b>
</pre>
<pre>///////////////////////////////////
// Date: August 13, 2003
// Author: Qingzhe Huang
// File: Driver.cpp
///////////////////////////////////
// Driver .cpp file and major feature is:
// 1.  I don't like copy&amp;paste same code, so I made a template function generalTest()
//     which takes the array object with parameter and also its type. Therefore, I can
//	   test all type of template array with this templated function.
// 2.  Originally I also want to test array with object, say a user-defined class &quot;Student&quot;,
//	   but it takes more time. (this class must define &quot;operator==&quot; as my array need this in
//	   its member function, so does &quot;assign operator=&quot;.	
// 
///////////////////////////////////

#include &lt;iostream&gt;
#include &quot;Array.h&quot;
#include &quot;Exception.h&quot;

using namespace std;

//this template function can test all data type provided
//user pass a data array with same data type of the array class
template&lt;class T&gt;
void generalTest(Array&lt;T&gt;&amp; A, T* dataArray);

int main()
{
	char* strArray[6]={&quot;str1&quot;,&quot;str2&quot;,&quot;str3&quot;,&quot;str4&quot;,&quot;str5&quot;,&quot;str6&quot;};
	int integerArray[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
		
	Array&lt;int&gt; intArray(12);
	Array&lt;char*&gt; charArray(6);
	
	//test int type with int data array
	generalTest&lt;int&gt;(intArray, integerArray);

	generalTest&lt;char*&gt;(charArray, strArray);

	return 0;
}

//this saves those copy&amp;paste garbage code as you don't need to write
//same code to test every data type.
template&lt;class T&gt;
void generalTest(Array&lt;T&gt;&amp; A, T* dataArray)
{
	cout&lt;&lt;&quot;test constructor by assign negative size\n&quot;;
	try
	{
		Array&lt;T&gt; temp(-1);
	}
	catch(Error E)
	{
		cout&lt;&lt;E.what()&lt;&lt;endl;
	}

	cout&lt;&lt;&quot;test friend function and operator[]&quot;&lt;&lt;endl;
	for (int i=0; i&lt;A.getSize(); i++)
	{
		A[i] = dataArray[i];
	}
	cout&lt;&lt;A&lt;&lt;endl;

	cout&lt;&lt;&quot;Here goes the try block, see if &quot;&quot;out of bounds&quot;&quot; error can be caught&quot;
		&lt;&lt;&quot; by access one more than size\n&quot;;
	try
	{
		cout&lt;&lt;&quot;The size of object is &quot;&lt;&lt;A.getSize()&lt;&lt;endl;
		cout&lt;&lt;&quot;try to access one more than size&quot;&lt;&lt;endl;
		cout&lt;&lt;A[A.getSize()+1];
	}
	catch(Error E)
	{
		cout&lt;&lt;E.what()&lt;&lt;endl;
	}
	cout&lt;&lt;&quot;now test operator== by compare object itself\n&quot;;
	cout&lt;&lt;&quot;A==A should be: &quot;&lt;&lt;(A==A?&quot;true&quot;:&quot;false&quot;)&lt;&lt;endl;
	cout&lt;&lt;&quot;now test operator == by compare object with different size\n&quot;;
	Array&lt;T&gt; B(A.getSize()-1);

	for (i=0; i&lt;B.getSize(); i++)
	{
		B[i] = dataArray[i];
	}
	cout&lt;&lt;&quot;A, B with different size,so (A==B) should be: &quot;&lt;&lt;(A==B?&quot;true&quot;:&quot;false&quot;)&lt;&lt;endl;
	cout&lt;&lt;&quot;now test copy constructor\n&quot;;
	Array&lt;T&gt; C(A);

	cout&lt;&lt;&quot;C is created by initialized by A, so C==A should be: &quot;
		&lt;&lt;(C==A?&quot;true&quot;:&quot;false&quot;)&lt;&lt;endl;

	cout&lt;&lt;&quot;now try to catch No Memory Allocated by allocating too much memory\n&quot;;

	try
	{
		Array&lt;T&gt; D(999999999);
	}
	catch(Error E)
	{
		cout&lt;&lt;E.what()&lt;&lt;endl;
	}
	cout&lt;&lt;&quot;Now try substring function by passing nagative subscript\n&quot;;
	try
	{
		cout&lt;&lt;A(-1, A.getSize() -2);
	}
	catch(Error E)
	{
		cout&lt;&lt;E.what()&lt;&lt;endl;
	}
	cout&lt;&lt;&quot;try to test last is smaller than first\n&quot;;
	try
	{
		cout&lt;&lt;A(A.getSize()-4, A.getSize()-5);
	}
	catch(Error E)
	{
		cout&lt;&lt;E.what()&lt;&lt;endl;
	}
	cout&lt;&lt;&quot;try to get correct substring\n&quot;;
	try 
	{
		cout&lt;&lt;&quot;original array is like this\n&quot;&lt;&lt;A&lt;&lt;endl;
		cout&lt;&lt;&quot;now substring is like this\n&quot;&lt;&lt;A(A.getSize()-5, A.getSize()-3)&lt;&lt;endl;
	}
	catch(Error E)
	{
		cout&lt;&lt;E.what()&lt;&lt;endl;
	}
}


</pre>
<pre>
	</pre>
<pre></pre>
<pre>
</pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre><b><font color="#FF0000" size="3"><span lang="en-ca"><a name="result"></a>Running result of program:</span></font></b></pre>
<pre></pre>
<pre>　</pre>
<pre>	</pre>
<pre></pre>
<pre>			
</pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="WhoAmI.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>