Getting Started:
Demonstrate how to build an Application with Tasks

ATest.h, ATest.cpp, Executive.h, Executive.cpp
Task1.h, Task1.cpp, Task2.h, Task2.cpp, Task3.h, Task3.cpp
GS.txt


#pragma once
/////////////////////////////////////////////////////////////////////
// ATest.h - abstract base class for self testing classes
//
#include <iostream>
#include <functional>

struct ATest
{
  /*---< non-virtual function inherited by all derived classes >---*/
  /*
   *  This function runs each of the derived classes' test()s
   *  inside a try-catch block, so we don't have to handle
   *  exceptions in those functions.
   */
  bool testPackage()
  {
    std::cout << "\n--entering " << typeid(*this).name() << "::testPackage()";
    try
    {
      return test();
    }
    catch (std::exception& ex)
    {
      std::cout << "\n--exception thrown in " << typeid(*this).name() << "::testPackage()";
      std::cout << "\n  " << ex.what();
      return false;
    }
  }
  /*----< handle exceptions thrown in member functions >-----------*/

  template <typename T>
  using MemFunPtr = void(T::*)();

  template<typename T>
  void safeInvoke(T& worker, MemFunPtr<T> workItem, unsigned int errorLineNumber = 0)
  {
    try
    {
      (worker.*workItem)();  // syntax for invoking member pointer
    }
    catch (std::exception& ex)
    {
      std::cout << "\n--exception thrown in " << typeid(*this).name();
      if(errorLineNumber != 0)
        std::cout << " at line number " << errorLineNumber;
      std::cout << "\n--" << ex.what();
    }
  }
  /*----< pure virtual function all derived classes implement >----*/

  virtual bool test()=0;
  
  /*----< virtual destructor redefined by each derived class >-----*/

  virtual ~ATest() {}
};