Desktop Programming > C/C++ & Visual C++
class Vector ... and Stacks and Queues ...
David:
Finally ... as a template ...
--- Code: ---// MyArray3.h //
#ifndef MYARRAY_H
#define MYARRAY_H
#include <iostream>
using std::cerr;
// 3rdly as a template ...
template < typename T >
class MyArray
{
public:
// ctors...
// default ctor ...
MyArray() : len(0), cap(0), ary(0) {}
//with size passed in
MyArray( size_t size ) : len(size), cap(size), ary( new T [len] )
{
for( size_t i = 0; i < len; ++i ) ary[i] = T();
}
// with ary (beg, end) passed in ...
MyArray( const T* beg, const T* end )
{
len = cap = end - beg;
ary = new T[len];
for( size_t i = 0; i < len; ++i ) ary[i] = beg[i];
}
// copy ctor...
MyArray ( const MyArray< T >& v ) // copy constructor ...
{
cap = v.cap;
len = v.len;
ary = new T[cap];
for( size_t i = 0; i < len; ++i ) ary[i] = v.ary[i];
}
// overloaded operateo = ...
MyArray< T >& operator = ( const MyArray< T >& v ) // copy constructor ...
{
if( this != &v )
{
delete [] ary;
cap = v.cap;
len = v.len;
ary = new T[cap];
for( size_t i = 0; i < len; ++i ) ary[i] = v.ary[i];
}
return *this;
}
// clear ...
void clear()
{
if( ary )
{
delete [] ary;
cap = 0;
len = 0;
ary = 0;
}
}
// destructor ..
~MyArray() { clear(); }
// reserve ...
void reserve( size_t newCap )
{
if( newCap > cap )
{
cap = newCap;
T* tmp = new T[ cap ];
for( size_t i = 0; i < len; ++i ) tmp[i] = ary[i];
delete [] ary;
ary = tmp; // update the base address of ary
}
}
// resize ...
void resize( size_t newSize )
{
if( newSize > len )
{
reserve( newSize );
for( size_t i = cap-1; i >= len; --i ) ary[i] = T();
len = newSize;
}
else if( newSize < len )
{
for( size_t i = len-1; i >= newSize; --i ) ary[i] = T();
len = newSize;
}
}
// push_back ...
void push_back( const T& val )
{
if( len == cap ) enlarge();
/* now add in new element ... */
ary[len] = val;
++ len;
}
// overloaded operator [] ...
T& operator [] ( size_t i ) { return ary[i]; } // allow element to be updated
const T& operator [] ( size_t i ) const { return ary[i]; } // 'read only'
size_t size() const { return len; }
size_t capacity() const { return cap; }
const T& back() const
{
if( len ) return ary[len-1];
// else ...
cerr << "\nERROR! MyArray is empty ... return value of 0 is NOT valid.\n";
return errVal;;
}
T& back()
{
if( len ) return ary[len-1];
// else ...
cerr << "\nERROR! MyArray is empty ... return value of 0 is NOT valid.\n";
return errVal;;
}
void pop_back() { if( len ) --len; }
bool empty() const { return len == 0; }
private:
size_t len;
size_t cap;
T* ary;
static T errVal;
// enlarge
void enlarge()
{
if( cap ) cap += cap; // double capacity ...
else cap = 2; // set initial capacity
T* tmp = new T[ cap ];
for( size_t i = 0; i < len; ++i ) tmp[i] = ary[i];
//for( int i = cap-1; i >= len; --i ) tmp[i] = T();
delete [] ary;
ary = tmp; // update the base address of ary
}
} ;
// initail here ... //
template< typename T >
T MyArray< T >::errVal = T();
#endif
--- End code ---
And a cheap little test file ...
--- Code: ---// test_MyIntArray3.h.cpp // // 2016-02-28 //
#include "MyIntArray3.h"
#include <string>
int main()
{
using namespace std;
const int nums[]= { 5, 4, 3, 2, 1 };
const int size = sizeof nums / sizeof(int);
MyArray < int > v( nums, nums+size );
MyArray < int > cpy( v ), a;
a = cpy;
for( size_t i = 0; i < v.size(); ++ i ) cout << v[i] << ' ';
cout << '\n';
for( size_t i = 0; i < cpy.size(); ++ i ) cout << cpy[i] << ' ';
cout << '\n';
for( size_t i = 0; i < a.size(); ++ i ) cout << a[i] << ' ';
cout << "\n\n";
while( !a.empty() )
{
cout << a.back() << ' ';
a.pop_back();
}
cout << "\n\n";
const string strs[] = { "5", "4", "3", "2", "1" };
const int sizeStrs = sizeof strs / sizeof(string);
MyArray < string > vStr( strs, strs+sizeStrs );
MyArray < string > cpyStr( vStr ), aStr;
aStr = cpyStr;
for( size_t i = 0; i < vStr.size(); ++ i ) cout << vStr[i] << ' ';
cout << '\n';
for( size_t i = 0; i < cpyStr.size(); ++ i ) cout << cpyStr[i] << ' ';
cout << '\n';
for( size_t i = 0; i < aStr.size(); ++ i ) cout << aStr[i] << ' ';
cout << "\n\n";
while( !aStr.empty() )
{
cout << aStr.back() << ' ';
aStr.pop_back();
}
cout << "\nPrees 'Enter' to exit/continue ... ";
cin.get();
}
--- End code ---
David:
Now to some simple stacks demo'd ...
--- Code: ---// Stack.h // // 2016-02-29 //
#ifndef dwSTACK_H
#define dwSTACK_H
#include <iostream>
#include <vector>
// default container for *THIS CUSTOM* stack here is std:: vector< T > //
template < typename T, class Container = std::vector < T > >
class Stack
{
public:
void push( const T& val ) { stk.push_back( val ); }
///////// NOTE! *NO* bounds checking is done here /////
const T& top() const { return stk.back(); }
T& top() { return stk.back(); }
void pop() { stk.pop_back(); }
////////////////////////////////////////////////////////
size_t size() const { return stk.size(); }
bool empty() const { return stk.empty(); }
private:
Container stk;
} ;
#endif
--- End code ---
And a little test progrom ...
--- Code: ---// test_Stack.h.cpp // // 2016-02-29 //
#include "Stack.h"
#include <iostream> // included above //
#include <string>
#include <list>
#include <deque> // a double ended queue //
int main()
{
using namespace std;
const string names[] = { "Andy", "Bill", "Jill", "Lucy", "Marie", "Sam", "Sharon", "Zoe" };
const int num_names = sizeof names / sizeof *names;
Stack < string > vNames; // by default, container inside *THIS CUSTOM* Stack wrapper class is a vector //
for( int i = 0; i < num_names; ++ i ) vNames.push( names[i] );
cout << "Testing pop vNames: \n";
while( !vNames.empty() )
{
cout << vNames.top() << ' ';
vNames.pop();
}
// Note C++ list is a double_link linked list ...
// so has push_back and pop_back and back methods all implemented ok //
Stack < string, list< string > > lstNames; // here, using a list container inside the class Stack //
for( int i = 0; i < num_names; ++ i ) lstNames.push( names[i] );
cout << "\n\nTesting pop lstNames: \n";
while( !lstNames.empty() )
{
cout << lstNames.top() << ' ';
lstNames.pop();
}
Stack < string, deque< string > > deqNames; // here, using a deque container inside the class Stack //
for( int i = 0; i < num_names; ++ i ) deqNames.push( names[i] );
cout << "\n\nTesting pop deqNames: \n";
while( !deqNames.empty() )
{
cout << deqNames.top() << ' ';
deqNames.pop();
}
cout << "\n\nPress 'Enter' to continue/exit ... " << flush;
cin.get();
}
--- End code ---
David:
Now to Queues ...
--- Code: ---// Queue.h // // 2016-02-29 //
#ifndef dwQUEUE_H
#define dwQUEUE _H
#include <iostream>
#include <list>
// default container for stack here is std::list < T > //
template < typename T, typename Container = std::list < T > >
class Queue
{
public:
void push_back( const T& obj ) { que.push_back( obj ); }
///////// NOTE! *NO* bounds checking is done here /////
const T& back() const { return que.back(); }
T& back() { return que.back(); }
const T& front() const { return que.front(); }
T& front() { return que.front(); }
void pop_front() { que.pop_front(); }
////////////////////////////////////////////////////////
size_t size() const { return que.size(); }
bool empty() const { return que.empty(); }
private:
Container que;
} ;
#endif
--- End code ---
And a little test program ...
--- Code: ---// test_Queue.h.cpp // // 2016-02-13 //
#include "Queue.h"
#include <iostream> // included above //
#include <string>
#include <deque> // a double ended queue //
int main()
{
using namespace std;
const string names[] = { "Andy", "Bill", "Jill", "Lucy", "Marie", "Sam", "Sharon", "Zoe" };
const int num_names = sizeof names / sizeof *names;
// Note C++ list is a double_link linked list ...
// so has push_back and pop_back and back methods all implemented ok //
Queue < string > lstNames; // here, using default list container inside the class Queue //
for( int i = 0; i < num_names; ++ i ) lstNames.push_back( names[i] );
cout << "\n\nTesting pop_front lstNames: \n";
while( !lstNames.empty() )
{
cout << lstNames.front() << ' ';
lstNames.pop_front();
}
// here, using a deque container inside the class Queue //
Queue < string, deque< string > > deqNames;
for( int i = 0; i < num_names; ++ i ) deqNames.push_back( names[i] );
cout << "\n\nTesting pop_front deqNames: \n";
while( !deqNames.empty() )
{
cout << deqNames.front() << ' ';
deqNames.pop_front();
}
cout << "\n\nPress 'Enter' to continue/exit ... " << flush;
cin.get();
}
--- End code ---
Navigation
[0] Message Index
[*] Previous page
Go to full version