One approach could be to add functions and change the main method to call the function of the current exercise. Disadvantage of this approach: the main function needs to be changed when a different exercise is to be executed.
This framework in turn allows to add new exercises by simply coding the Exercise as a subclass of AbstractExercise and adding it to the project. No need to include the file anywhere via #include
.
You can choose at runtime which Exercises to run by providing the names of the Exercises to run on the commandline, e.g. (at the command prompt):
uebung.exe Fahrenheit2CelsuisExercise
or
uebung.exe Fahrenheit2CelsuisExercise Exercise2b Exercise3a MyExercise
AbstractExercise::getInput()
(for getting Input) and AbstractExercise::execute()
(for executing the Exercise).
The easiest approach is to take the HelloExercise
(see below) and replace all occurrences of the string "<code>HelloExercise</code>" by the name of your new Exercise class. Then proceed and replace the implementations of getInput()
and execute()
by your own.
Don't forget to add the following line to the source (.cpp
) of your Exercise:
namespace { MyExercise proto("MyExercise"); }
(replace "MyExercise" by the classname of your Exercise!)
Thus a "Hello World" Example for Exercise would be coded as file HelloExample.cpp
(try it!):
#include "macros.h" // needs to be declared as first entry in .cpp or .h file!
#include <iostream>
#include <string>
using namespace std;
#include "AbstractExercise.h"
class HelloExercise : public AbstractExercise {
public:
HelloExercise(string name) : AbstractExercise(name){}
protected:
void getInput();
void execute();
private:
string fUserName;
};
namespace {
HelloExercise proto("HelloExercise");
}
void HelloExercise::getInput(){
cout << "your name please :";
cin >> fUserName;
}
void HelloExercise::execute(){
cout << "Hello "<< fUserName <<", this is "<< getName() << endl;
}
The basic trick is that each Exercise creates an instance of itself. Thus the constructor of AbstractExercise gets called, which in turn adds the Exercise to the ExerciseStore. NOTE: This should be enhanced further by using Andrei Alexandrescu's Loki::Factory. This factory has the advantage of avoiding to instantiate every exercise, but instead registers creator functions that ensure that only those exercises actually required will be created.
The main function creates a Driver and calls its Driver::instantiate()
function for each argument given on the command line. The Driver::instantiate()
method consults the ExerciseStore to get the Exercise for the given argument. If the Exercise is found, its AbstractExercise::getInput()
method is called followed by its AbstractExercise::execute()
method.
When the main function has tried all arguments it terminates. The termination of Driver asks the ExerciseStore to delete all its Exercises.
© Bernhard Wagner, xmlizer.net, 2002-03.