Monday, March 12, 2018

Another Update



It is no shame to admit that this person is currently unable to make significant progress in solving Programming Challenge 16.12. As there is no way of telling how much longer it will take a decision had to be made. Instead of investing all energy into this one project, while there are still five chapters left to work through and many more Challenges waiting to be solved, this person has decided to continue on to the next chapter for now. 

Numerous possibilites were taken into consideration to determine what happens with Programming Challenge 16.12 in the meantime. For now the work on it will continue on the side. If it isn't taking away time and energy from the learning process, it will be kept up, until the problem is solved. Otherwise it will have to wait until the end of the book has been reached. This is for the reason that, since the newest revision of this book has some additional Programming Challenges in earlier chapters, solutions for these Challenges may also find their way to this blog. It is some additional exercise, so it would fit in well to come back to this as yet unsolved Challenge by that time.

For now, it is time to keep on learning, to make some progress, and to hopefully be able to finish this one Challenge soon. As always it is a pleasure to thank all visitors for the continued interest in this person's humble blog, a special pleasure to thank my followers for subscribing! To my fellow students, who may not have the luxury to move on, for whom there are grades at stake if they do not manage to solve a problem in time, don't despair and keep giving your best. When you are ready, get back to it and work on a solution in your own time, then solve it. Persistence is key!

Wednesday, March 7, 2018

Update

Dear readers, you may have noticed that there is a gap in numbers in between Programming Challenges 16.11 and 16.13. The reason is not that this person has skipped Challenge 16.12, quite the contrary. It is a very difficult challenge, thus it will take some more time to arrive at a solution, so instead this person decided to solve what felt to be a very easy last challenge of this chapter, then return to work on the more difficult one. This person will work hard to get it done soon, so as to be able to continue on to Chapter 17.

With this little update information out of the way, it is time for this person to take a small break to gather new mental energy, to finally also get done with Challenge 16.12. In the meantime I wish my readers, visitors old and new, and my fellow students all the best in their attempt to solve any problem however difficult it may seem! Give your best!

Programming Challenge 16.13 - Exceptions Project

Example Files: ExceptionsProject.7z

Employee.h


#ifndef EMPLOYEE_H_
#define EMPLOYEE_H_

#include <iostream>
#include <string>

class Employee
{
    private:
        int            employeeID;
        std::string employeeName;
        std::string employeeHireDate;

    public:
        class InvalidEmployeeID
        {
            private:   
                int invalidEmployeeID;

            public:
                InvalidEmployeeID(int invalidEmpID) : invalidEmployeeID(invalidEmpID)
                { }

                int getInvalidEmployeeID() const
                { return invalidEmployeeID; }
        };

        Employee(int, std::string, std::string);
        virtual ~Employee()
        { }

        // Mutator function
        void setEmployee(int, std::string, std::string);

        // Accessor function
        void invalidIDHandler() const;

        // Consider directly employing the overloaded operator and call it from the
        // Production worker class
        friend std::ostream &operator << (std::ostream &, const Employee &);
       
        virtual void print(std::ostream &) const;
};

#endif

Employee.cpp


#include "Employee.h"

#include <iomanip>

/* **********************************************************
            Employee::Employee() : int, string, string
            - Constructor
   ********************************************************** */

Employee::Employee(int empID, std::string empName, std::string empHired) :
    employeeID(empID), employeeName(empName), employeeHireDate(empHired)
{
    invalidIDHandler();
}

/* **********************************************************
            Employee::setEmployee() : int, string, string
    Sets the employee data.
   ********************************************************** */

void Employee::setEmployee(int empID, std::string empName, std::string empHired)
{
    employeeID = empID;
    employeeName = empName;
    employeeHireDate = empHired;

    invalidIDHandler();
}

/* **********************************************************
            Employee::invalidIDHandler()
    Evaluates the employeeID and throws an exception if found
    invalid.
   ********************************************************** */

void Employee::invalidIDHandler() const
{
    if (employeeID < 0 || employeeID > 9999)
    {
        throw InvalidEmployeeID(employeeID);
    }
}

/* **********************************************************
            Overloaded << function
   ********************************************************** */

std::ostream &operator << (std::ostream &strm, const Employee &obj)
{
    obj.print(strm);
    return strm;
}

/* **********************************************************
            Employee::print() : ostream &
    Outputs the employee data to screen.
   ********************************************************** */

void Employee::print(std::ostream &strm) const
{
    strm << std::left  << std::setw(12) << "Employee Name: "
          << std::right << employeeName << std::endl;
    strm << std::left << std::setw(15) << "Employee ID: "
          << std::right << employeeID << std::endl;
    strm << std::left  << std::setw(15) << "Hire Date: "
          << std::right << employeeHireDate << std::endl << std::endl;
}

ProductionWorker.h


#ifndef PRODUCTION_WORKER_H_
#define PRODUCTION_WORKER_H_

#include "Employee.h"

#include <iostream>
#include <string>

class ProductionWorker : public Employee
{
    private:
        int     shiftNumber;
        double hourlyPayrate;

    public:
        class InvalidPayrate
        {
            private:
                double invalidPayrate;

            public:
                InvalidPayrate(double invalidRate) : invalidPayrate(invalidRate)
                { }

                double getInvalidPayrate() const
                { return invalidPayrate; };
        };

        class InvalidShiftData
        {
            private:
                int invalidShiftID;

            public:
                InvalidShiftData(int invalidShift) : invalidShiftID(invalidShift)
                { }

                int getInvalidShiftID() const
                { return invalidShiftID; }
        };

        ProductionWorker(int, std::string, std::string, int, double);

        void setProductionWorker(int, double);

        void invalidShiftHandler() const;
        void invalidPayrateHandler() const;

        void print(std::ostream &) const override;
};

#endif

ProductionWorker.cpp


#include "ProductionWorker.h"

#include <iomanip>

/* **********************************************************
            ProductionWorker::ProductionWorker() : int, string,
            string, int, double - Constructor
   ********************************************************** */

ProductionWorker::ProductionWorker(int empID, std::string empName, std::string empHired,
                                              int shiftID, double payRate) :
                                              shiftNumber(shiftID),hourlyPayrate(payRate),
                                              Employee(empID, empName, empHired)
{
    invalidShiftHandler();
    invalidPayrateHandler();
}

/* **********************************************************
            ProductionWorker::setProductionWorker() int, double
    Sets the production worker data.
   ********************************************************** */

void ProductionWorker::setProductionWorker(int shiftID, double payRate)
{
    shiftNumber = shiftID;
    hourlyPayrate = payRate;

    invalidShiftHandler();
    invalidPayrateHandler();
}

/* **********************************************************
            ProductionWorker::shiftErrorHandler()
    Evaluates the shiftNumber and throws an exception if found
    invalid.
   ********************************************************** */

void ProductionWorker::invalidShiftHandler() const
{
    if (shiftNumber < 0 || shiftNumber > 2)
    {
        throw InvalidShiftData(shiftNumber);
    }
}

/* **********************************************************
            ProductionWorker::payRateErrorHandler()
    Evaluates the hourlyPayRate and throws an exception if
    found invalid.
   ********************************************************** */

void ProductionWorker::invalidPayrateHandler() const
{
    if (hourlyPayrate < 0.0)
    {
        throw InvalidPayrate(hourlyPayrate);
    }
}

/* **********************************************************
            ProductionWorker::print() : ostream &
    Outputs the production worker data to screen.
   ********************************************************** */

void ProductionWorker::print(std::ostream &strm) const
{
    Employee::print(strm);

    strm << "Shift #" << shiftNumber << ": ";

    shiftNumber == 1 ?
        strm << std::setw(16) << std::right << "Day-Shift"   << std::endl :
        strm << std::setw(16) << std::right << "Night-Shift" << std::endl;

    strm << std::fixed << std::setprecision(2) << std::fixed;
    strm << std::left  << std::setw(14) << "Pay Rate: "
          << std::right << "$ " << hourlyPayrate << std::endl;
}

ExceptionProject.cpp


#include "ProductionWorker.h"

#include <iostream>

void badValueCheck(int, std::string, std::string, int, double);

int main()
{
    std::cout << "TAKEUCHI MANUFACTURING CO. - EMPLOYEE DATA VALIDATION\n\n";
    std::cout << "The following tests will now be carried out:\n\n";

    std::cout << "Test 1: Employee Number\n";
    badValueCheck(99921, "Flanders Moll", "17/04/2013", 2, 86.80);
    std::cout << std::endl;

    std::cout << "Test 2: Shift ID\n";
    badValueCheck(1241, " Kakuta", "12/03/2015", -7, 85.99);
    std::cout << std::endl;

    std::cout << "Test 3: Hourly Payrate\n";
    badValueCheck(9411, "Vishneva Diana", "12/03/2015", 1, -190.55);
    std::cout << std::endl;

    std::cout << "Test 4: Correct Data\n";
    badValueCheck(4350, "Hiroshi Sato", "15/05/2005", 2, 99.75);
    std::cout << std::endl;

    std::cout << "You are now leaving the Database System ...\n\n";
    std::cout << "TAKEUCHI MANUFACTURING CO.\n"
             << "Unrivaled quality, products with a difference,\n"
             << "and fast development responding to the users' needs.";

    std::cin.get();
    return 0;
}

/* **********************************************************
            badValueCheck() : int, string, string, int, double
    This function tests various data items for validity. If an
    item is invalid, it is caught, and an error message is
    output. Otherwise the production worker data is output.
   ********************************************************** */

void badValueCheck(int empID, std::string empName, std::string empHired,
                         int shiftID, double payRate)
{
    try
    {
        ProductionWorker temp(empID, empName, empHired, shiftID, payRate);

        std::cout << temp;
    }
    catch (ProductionWorker::InvalidEmployeeID badEmployeeID)
    {
        std::cout << "Error! Invalid Employee ID: "
                     << badEmployeeID.getInvalidEmployeeID() << std::endl;
    }
    catch (ProductionWorker::InvalidShiftData badShiftID)
    {
        std::cout << "Error! Invalid Shift ID: "
                     << badShiftID.getInvalidShiftID() << std::endl;
    }
    catch (ProductionWorker::InvalidPayrate badPayrate)
    {
        std::cout << "Error! Invalid Hourly Payrate: $ "
                     << badPayrate.getInvalidPayrate() << std::endl;
    }
}

Example Output:



Monday, February 26, 2018

Programming Challenge 16.11 - Inheritance Modification

Example Files: InheritanceModification.7z

Notice: The only file that has directly changed is the SearchableVector class. The other files remain the same, and are to be found in the Example Files archive, but are not republished here.

SearchableVector.h


#ifndef SEARCHABLE_VECTOR_H_
#define SEARCHABLE_VECTOR_H_

#include "SortableVector.h"

template <class T>
class SearchableVector : public SortableVector<T>
{
    public:
        // Constructors
        SearchableVector() : SortableVector<T>()
        { }

        SearchableVector(int size) : SortableVector<T>(size)
        { }

        SearchableVector(const SearchableVector &);
   
        // Accessor function
        void findItem(const T &);
        int sortAndSearch(const T &);
};

/* **********************************************************
            SearchableVector<T>::SearchableVector()
         - Copy Constructor
   ********************************************************** */

template <class T>
SearchableVector<T>::SearchableVector(const SearchableVector &obj) :
                           SortableVector<T>(obj)
{
}

/* **********************************************************
            SearchableVector<T>::findItem() : const T &
    This function passes the value to search for in a given
    array to the sortAndSearch function. If the value exists,
    it is output. Otherwise a message indicating that the
    value does not exist is output.
   ********************************************************** */

template<class T>
void SearchableVector<T>::findItem(const T &val)
{
    int result = 0;

    result = this->sortAndSearch(val);

    if (result == -1)
    {
        cout << val << " does not exist ...\n\n";
    }
    else
    {
        cout << val << " was found at subscript position "
              << result << "\n\n";
    }
}

/* **********************************************************
            SearchableVector<T>::sortAndSearch() const T &
    This function first sorts an array, by calling the
    SortableVector class's sortItems() function, then a binary
    search algorithm is used, to find a value in it. If the
    value is found, the position is returned. Otherwise -1 is
    returned.
    ********************************************************** */

template <class T>
int SearchableVector<T>::sortAndSearch(const T &item)
{
    SortableVector<T>::sortItems();
   
    int  firstElem = 0;
    int  midPoint = 0;
    int  lastElem = SimpleVector<T>::getArraySize() - 1;
    int  position = -1;
    bool status = false;

    while (status == false && firstElem <= lastElem)
    {
        midPoint = (firstElem + lastElem) / 2;

        if (SimpleVector<T>::operator[](midPoint) == item)
        {
            position = midPoint;
            status = true;
        }

        SimpleVector<T>::operator[](midPoint) > item ? lastElem = midPoint - 1 :
                                                                 firstElem = midPoint + 1;
    }

    return position;
}

#endif

InheritanceMod.cpp


#include "SearchableVector.h"

#include <cstdlib>
#include <ctime>

#include <iostream>
using std::cin;
using std::cout;

#include <string>
using std::string;

/* **********************************************************
            print() : const <T> &obj, const string
    Outputs the object's current contents to screen.
    ********************************************************** */

template <class T>
void print(const SearchableVector<T> &obj, const string objName)
{
    cout << "These values are currently in your " << objName << ":\n";
    cout << obj << "\n\n";
}

/* **********************************************************
                                        main()
   ********************************************************** */

int main()
{
    const int    SIZE = 16;
    const string objNames[] = { "intTable", "doubleTable", "charTable" };

    srand(static_cast<unsigned int> (time(0)));

    SearchableVector<int>    intTable(SIZE);
    SearchableVector<double> doubleTable(SIZE);
    SearchableVector<char>   charTable(SIZE);

    cout << "SORTABLE AND SEARCHABLE VECTOR DEMO\n\n";
    cout << "Now filling the arrays with random values ...\n\n";
    for (int count = 0; count < SIZE; count++)
    {
        intTable[count] = rand() % SIZE + (count * 2);
        doubleTable[count] = rand() % SIZE * (count * 2.2);
        charTable[count] = rand() % SIZE - 191;
    }

    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Now sorting and searching for values in the arrays:\n\n";
    intTable.findItem(22);
    doubleTable.findItem(132.0);
    charTable.findItem('I');

    cout << "These are the items now in sorted order:\n\n";
    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Thank you for trying this program! Have a nice day!";
    cin.get();
   return 0;
}

Example Output:





Programming Challenge 16.10 - SortableVector Class Template

Example Files: SortableVectorClassTemplate.7z

SortableVector.h


#ifndef SORTABLE_VECTOR_H_
#define SORTABLE_VECTOR_H_

#include "SimpleVector.h"

template <class T>
class SortableVector : public SimpleVector<T>
{
    public:
        SortableVector() : SimpleVector<T>()
        { }

        SortableVector(int size) : SimpleVector<T>(size)
        { }

        SortableVector(const SortableVector &);

        // Mutator function
        void sortItems();
};

/* **********************************************************
            SortableVector<T>::SortableVector()
         - Copy Constructor
   ********************************************************** */

template <class T>
SortableVector<T>::SortableVector(const SortableVector &obj) :
                      SimpleVector<T>(obj.getArraySize())
{
    for (int count = 0; count < this->getArraySize(); count++)
    {
        this->operator[](count) = obj[count];
    }
}

/* **********************************************************
            SortableVector<T>::sortItems() : const T &
   This function uses a selection sort algorithm to sort the
    array's elements in ascending order.
   ********************************************************** */

template <class T>
void SortableVector<T>::sortItems()
{
    int startScan = 0;
    int index = 0;
    int minIndex = 0;
    T minValue{};

    for (; startScan < this->getArraySize() - 1; startScan++)
    {
        minIndex = startScan;
        minValue = this->operator[](startScan);

        for (index = startScan + 1; index < this->getArraySize(); index++)
        {
            if (this->operator[](index) < minValue)
            {
                minValue = this->operator[](index);
                minIndex = index;
            }
        }

        this->operator[](minIndex) = this->operator[](startScan);
        this->operator[](startScan) = minValue;
    }
}

#endif

SortableVectorDm.cpp


#include "SortableVector.h"

#include <cstdlib>
#include <ctime>

#include <iostream>
using std::cin;
using std::cout;

#include <string>
using std::string;

/* **********************************************************
            print() : const <T> &obj, const string
    Outputs the object's current contents to screen.
    ********************************************************** */

template <class T>
void print(const SortableVector<T> &obj, const string objName)
{
    cout << "These values are currently in your " << objName << ":\n";
    cout << obj << "\n\n";
}

/* **********************************************************
                                        main()
   ********************************************************** */

int main()
{
    const int    SIZE = 16;
    const string objNames[] = { "intTable", "doubleTable", "charTable" };

    srand(static_cast<unsigned int> (time(0)));

    SortableVector<int>    intTable(SIZE);
    SortableVector<double> doubleTable(SIZE);
    SortableVector<char>   charTable(SIZE);

    cout << "SORTABLE VECTOR DEMO\n\n";
    cout << "Now filling the arrays with random values ...\n";
    for (int count = 0; count < SIZE; count++)
    {
        intTable[count] = rand() % SIZE * 1 + (4 * 2);
        doubleTable[count] = rand() % SIZE * (count + (4 * 3.44));
        charTable[count] = rand() % SIZE - 191;
    }

    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Now sorting the items ...\n\n";
    intTable.sortItems();
    doubleTable.sortItems();
    charTable.sortItems();
   
    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Thank you for trying this program! Have a nice day!";
    cin.get();
   return 0;
}

ExampleOutput:



Sunday, February 25, 2018

Programming Challenge 16.9 - SearchableVector Modification

Example Files: SearchableVectorModification.7z

Notice: Since no changes have been made to the SimpleVector class, it is included in the Example Files archive, but not republished here. Most of the code for this project is taken from pp. 1020 through 1022 in the 9th Edition, or 1002 through 1004 in the 8th Edition of this book.

SearchableVector.h


#ifndef SEARCHABLE_VECTOR_H_
#define SEARCHABLE_VECTOR_H_

#include "SimpleVector.h"

template <class T>
class SearchableVector : public SimpleVector<T>
{
    public:
        // Constructors
        SearchableVector() : SimpleVector<T>()
        { }

        SearchableVector(int size) : SimpleVector<T>(size)
        { }

        SearchableVector(const SearchableVector &);

        // Accessor function
        int findItem(const T &);
};

/* **********************************************************
            SearchableVector<T>::SearchableVector()
         - Copy Constructor
   ********************************************************** */

template <class T>
SearchableVector<T>::SearchableVector(const SearchableVector &obj) :
                             SimpleVector<T>(obj.getArraySize())
{
    for (int count = 0; count < this->getArraySize(); count++)
    {
        this->operator[](count) = obj[count];
    }
}

/* **********************************************************
            SearchableVector<T>::findItem() : const T
    This function uses a binary search algorithm to find an
    item. If the item is found the subscript is returned.
    Otherwise -1 is returned.
   ********************************************************** */

template <class T>
int SearchableVector<T>::findItem(const T &item)
{
    int  firstElem = 0;
    int  midPoint = 0;
    int  lastElem = this->getArraySize() - 1;
    int  position = -1;
    bool status = false;

    while (status == false && firstElem <= lastElem)
    {
        midPoint = (firstElem + lastElem) / 2;

        if (this->operator[](midPoint) == item)
        {
            position = midPoint;
           status = true;
        }
       
        this->operator[](midPoint) > item ? lastElem = midPoint - 1 :
                                                        firstElem = midPoint + 1;
    }

    return position;
}

#endif

SearchableVectorMod.cpp


#include "SearchableVector.h"

#include <iostream>
using std::cin;
using std::cout;

#include <string>
using std::string;


/* **********************************************************
            findVal() : const <T> &obj, const T &, const string
    This function searches for a value in the object's array.
    If -1 is returned from the findItem() function, a message
    is output to indicate the fact that the value does not
    exist. Otherwise the value and subscript it was found at
    is output.
   ********************************************************** */

template <class T>
void findVal(SearchableVector<T> &obj, const T &val)
{
    int result = 0;

    result = obj.findItem(val);

    if (result == -1)
    {
        cout << val << " does not exist ...\n\n";
    }
    else
    {
        cout << val << " was found at subscript position "
              << result << "\n\n";
    }
}

/* **********************************************************
            print() : const <T> &obj, const string
    Outputs the object's current contents to screen.
    ********************************************************** */

template <class T>
void print(const SearchableVector<T> &obj, const string objName)
{
    cout << "These values are currently in your " << objName << ":\n";
    cout << obj << "\n\n";
}

/* **********************************************************
                            Function Definition
   ********************************************************** */

void printIntro();
void printOptions(const string *);

/* **********************************************************
                                        main()
   ********************************************************** */

int main()
{
    const int SIZE = 12;
    int       intVal = 0;
    int       choice = ' ';
    double    doubleVal = 0.0;
    char      charVal = ' ';
   
    const enum   options { INT = 1, DOUBLE = 2, CHAR = 3, PRINT = 4, QUIT = 5 };
    const string objNames[] = { "intTable", "doubleTable", "charTable" };

    SearchableVector<int>     intTable(SIZE);
    SearchableVector<double> doubleTable(SIZE);
    SearchableVector<char>   charTable(SIZE);

    printIntro();

    for (int count = 0; count < SIZE; count++)
    {
        intTable[count] = (count * 2);
        doubleTable[count] = (count * 2.14);
        charTable[count] = ((char)count - 191);  
    }

    do
    {
        printOptions(objNames);
        cout << "Choice: ";
        cin >> choice;

        while (choice < INT || choice > QUIT)
        {
            cout << "Choice: ";
            cin >> choice;
        }
        cout << "\n";

        switch (choice)
        {
            case INT:
            {
                cout << "Enter an integer value to search for: ";
                cin >> intVal;

                findVal(intTable, intVal);
            } break;

            case DOUBLE:
            {
                cout << "Enter an floating-point value to search for: ";
                cin >> doubleVal;

                findVal(doubleTable, doubleVal);
            } break;

            case CHAR:
            {
                cout << "Enter a character to search for: ";
                cin >> charVal;

                findVal(charTable, charVal);
            } break;

            case PRINT:
            {
                print(intTable, objNames[0]);
                print(doubleTable, objNames[1]);
                print(charTable, objNames[2]);
            } break;

            case QUIT:
            {
                cout << "Thank you for trying this program! Have a nice day!";
            } break;
        }
    } while (choice != QUIT);

    cin.get();
    cin.ignore();
   return 0;
}

/* **********************************************************
            printIntro() : const int
    Outputs information about the program's purpose and
    functionality.
   ********************************************************** */

void printIntro()
{
    cout << "SEARCHABLE VECTOR DEMO\n\n";
    cout << "This program let's you search for a value in an integer,\n"
           << "a floating-point, and a character array.\n\n";
    cout << "If the value exists, it will be output to screen. Otherwise\n"
          << "you will see a message telling you that the value does not exist.\n";
    cout << "You can repeat a search as many times as you wish to, or you\n"
          << "can quit the program and try again another time.\n\n";
}

/* **********************************************************
            printOptions() : const string *
    Outputs the available menu options.
   ********************************************************** */

void printOptions(const string *objNames)
{
    cout << "SEARCH TABLE:\n\n";
    cout << "1) " << objNames[0] << "\n";
    cout << "2) " << objNames[1] << "\n";
    cout << "3) " << objNames[2] << "\n";
    cout << "4) " << "Print Values\n";
    cout << "5) Quit\n\n";
}

Example Output:






Saturday, February 24, 2018

Programming Challenge 16.8 - SimpleVector Modification

Example Files: SimpleVectorModification.7z

Notice: Most of the code for this program is taken from chapter 16, pp. 1015 through 1019 in the 9th Edition, or pp. 997 through 1001 in the 8th Edition of this book.

SimpleVector.h


#ifndef SIMPLE_VECTOR_H_
#define SIMPLE_VECTOR_H_

#include <cstdlib>
#include <iostream>
#include <new>

template <class T>
class SimpleVector
{
    private:
        T    *aptr;
        int arraySize;
        int maxCapacity;

        void memError();
        void subError();

        template <class TPrint>
        friend std::ostream &operator << (std::ostream &, const SimpleVector<TPrint> &);

    public:
        SimpleVector();
        SimpleVector(int);
        SimpleVector(const SimpleVector &);
        ~SimpleVector();

        // Mutator functions
        void push_back(const T &);
        void pop_back();

        // Accessor functions
        int getArraySize() const
        { return arraySize; }
       
        T getElementAt(int);   
        T &operator [](const int &);
};

/* **********************************************************
            SimpleVector<T>::SimpleVector() - Constructor
   ********************************************************** */

template <class T>
SimpleVector<T>::SimpleVector()
{
    arraySize = 0;
    maxCapacity = 0;
}

/* **********************************************************
            SimpleVector<T>::SimpleVector() - Constructor
   ********************************************************** */

template <class T>
SimpleVector<T>::SimpleVector(int arrSize)
{
    arraySize = arrSize;

    try
    {
        aptr = new T[arrSize];
    }
    catch (std::bad_alloc)
    {
        memError();
    }

    for (int count = 0; count < arraySize; count++)
    {
        *(aptr + count) = 0;
    }
}
   
/* **********************************************************
            SimpleVector<T>::SimpleVector() - Copy Constructor
   ********************************************************** */

template <class T>
SimpleVector<T>::SimpleVector(const SimpleVector &obj)
{
    arraySize = obj.arraySize;

    aptr = new T[arraySize];

    if (aptr == 0)
    {
        memError();
    }

    for (int count = 0; count < arraySize; count++)
    {
        *(aptr + count) = *(obj.aptr + count);
    }
}

/* **********************************************************
            SimpleVector<T>::~SimpleVector() - Destructor
   ********************************************************** */

template <class T>
SimpleVector<T>::~SimpleVector()
{
    if (arraySize > 0)
    {
        delete [] aptr;
    }
}

/* **********************************************************
            SimpleVector<T>::pushBack() : const T, int &
    This function emulates a vector's push_back function. It
    dynamically allocates a temporary array of size n+1, then
    copies the original array's values to it. Next, the last
    element of the new array is assigned the tempVal's value
    before the original array is deleted. Before returning,
    the original array is caused to point to the new array,
    and the arraySize member variable gets incremented.
   ********************************************************** */

template <class T>
void SimpleVector<T>::push_back(const T &tempVal)
{
    T *tempAptr = new T[arraySize + 1];

    for (int count = 0; count < arraySize; count++)
    {
        *(tempAptr + count) = *(aptr + count);
    }
   
    delete[] aptr;
    aptr = tempAptr;
   
    *(aptr + arraySize) = tempVal;

    arraySize++;
}

/* **********************************************************
            SimpleVector<T>::pop_back() : int &
    This function emulates a vector's pop_back function. If
    arraySize is greater 0, the maxCapacity and arraySize will
    get decremented. Next, a temporary array is dynamically
    allocated, to which the original array's values n-1 are
    copied. Then, the original array is deleted, and caused to
    point to the new array. Otherwise, the memError() function
    is called, and the program exits with an error message.
   ********************************************************** */

template <class T>
void SimpleVector<T>::pop_back()
{
    if (arraySize > 0)
    {
        maxCapacity = --arraySize;

        T *tempPtr = new T[maxCapacity];

        for (int count = 0; count < maxCapacity; count++)
        {
            *(tempPtr + count) = *(aptr + count);
        }

        delete[] aptr;
        aptr = tempPtr;
    }
    else
    {
        memError();
    }
}

/* **********************************************************
            T SimpleVector<T>::getElementAt() : int
    This function returns the value stored at the subscript
    in the array.
   ********************************************************** */

template <class T>
T SimpleVector<T>::getElementAt(int subPos)
{
    if (subPos < 0 || subPos >= arraySize)
    {
        subError();
    }

    return aptr[subPos];
}

/* **********************************************************
            T &SimpleVector<T>::operator[]() : const int &
         - Overloaded [] operator
    This function returns a reference to the element in the
    array indexed by the subscript.
   ********************************************************** */

template <class T>
T &SimpleVector<T>::operator[](const int &subPos)
{
    if (subPos < 0 || subPos >= arraySize)
    {
        subError();
    }

    return aptr[subPos];
}

/* **********************************************************
            SimpleVector<T>::subError()
    Displays an error message and terminates the program when
    a subscript is out of range.
    ********************************************************** */

template <class T>
void SimpleVector<T>::subError()
{
    cout << "ERROR: Subscript out of range.\n";
    cin.get();
    cin.ignore();
    exit(EXIT_FAILURE);
}

/* **********************************************************
            SimpleVector<T>::memError()
    Displays an error message and terminates the program when
    memory allocation fails.
   ********************************************************** */

template <class T>
void SimpleVector<T>::memError()
{
    cout << "ERROR: Cannot allocate memory.\n";
    cout << "This program will now exit ...\n";
    std::cin.get();
    std::cin.ignore();
    exit(EXIT_FAILURE);
}

/* **********************************************************
            Overloaded Extraction Operator <<
   ********************************************************** */

template <class T>
std::ostream &operator << (std::ostream &strm, const SimpleVector<T> &obj)
{
    for (int count = 0; count < obj.arraySize; count++)
    {
        strm << (*(obj.aptr + count)) << ' ';
    }

    return strm;
}

#endif

SimpleVectorMod.cpp


#include "SimpleVector.h"

#include <iostream>
using std::cin;
using std::cout;

/* **********************************************************
                            Function Definition
   ********************************************************** */

void printIntro(const int);

int main()
{
    int     SIZE = 10;
    int     count = 0;
    int     intVal = 0;
    double doubleVal = 0;
    char   characterVal = ' ';
    char     choice = ' ';
   
    SimpleVector<int>        intTable(SIZE);
    SimpleVector<double> doubleTable(SIZE);
    SimpleVector<char>   charTable(SIZE);

    printIntro(SIZE);

    cout << "Now filling the arrays with initial values. Please be patient!\n";
    for (; count < SIZE; count++)
    {
        intTable[count] = (count * 2);
        doubleTable[count] = (count * 2.14);
        charTable[count] = count;
    }

    cout << "\nThese are the values currently in your intTable:\n";
    cout << intTable << "\n\n";
    cout << "These are the values currently in your doubleTable:\n";
    cout << doubleTable << "\n\n";
    cout << "These are the values currently in your charTable:\n";
    cout << charTable << "\n\n";

    do
    {
        cout << "Please enter an int value: ";
        cin >> intVal;
        intTable.push_back(intVal);

        cout << "Please enter a floating-point value (Ex: 7.5): ";
        cin >> doubleVal;
        doubleTable.push_back(doubleVal);

        cout << "Please enter a character: ";
        cin >> characterVal;   
        charTable.push_back(characterVal);

        cout << "\nDo you wish to add another set of values (Y/N)? ";
        cin >> choice;
        cout << "\n";

        while (toupper(choice) != 'Y' && toupper(choice) != 'N')
        {
            cout << "\nDo you wish to add another set of values (Y/N)? ";
            cin >> choice;
        }
    } while (toupper(choice) != 'N');

    cout << "These are the values now in your intTable:\n";
    cout << intTable << "\n\n";
    cout << "These are the values now your doubleTable:\n";
    cout << doubleTable << "\n\n";
    cout << "These are the values now in your charTable:\n";
    cout << charTable << "\n\n";

    cout << "Some values will no be removed from your arrays.\n";
    for (count = intTable.getArraySize(); count > 4; count--)
    {
        intTable.pop_back();
        doubleTable.pop_back();
        charTable.pop_back();
    }

    cout << "\nThese are the new values in your intTable:\n";
    cout << intTable << "\n\n";
    cout << "These are the new values in your doubleTable:\n";
    cout << doubleTable << "\n\n";
    cout << "These are the new values in your charTable:\n";
    cout << charTable << "\n\n";

    cout << "This is the end of the Simple Vector demo. Have a nice day!";

    cin.get();
    cin.ignore();
   return 0;
}

/* **********************************************************
            printIntro() : const int
    Outputs information about the program's purpose and
    functionality.
   ********************************************************** */

void printIntro(const int SIZE)
{
    cout << "SIMPLE VECTOR DEMO\n\n";
    cout << "This program emulates functionality in the STL vector class:\n"
           << "   1.] push_back()\n"
          << "   2.] pop_back()\n\n";
    cout << "The program will fill two arrays with an initial set of "
          << SIZE << " values.\n";
    cout << "Then, you are asked to input an integer, a floating-point value,\n"
          << "and a character, which are added to the appropriate array, to\n"
         << "demonstrate how the push_back() function works.\n";
    cout << "Before the program exits, some values will be removed from the\n"
          << "arrays, to demonstrate how the pop_back() function works.\n\n";
}

Example Output: