Hi all,
I’ve been given told to convert a standard C++ program into an object-oriented one, using the principals of polymorphism, encapsulation and inheritance. Our lecturer covered all three principals in one 45 minute slot. I’m completely stuck and would be grateful for any help.
The standard C++ program accepts data values and filter values from the user. It then multiplies these values together using a simple algorithm and prints the output to the screen. The standard program is shown below.
I haven’t made much of a start as I’m unsure how to allocate the classes. I’ve allocated one class to the TheFilter structure with its associated data and functions, and another to the TheData structure.
I hate to admit defeat, but I’ve never programmed using an object-oriented approach and I’ve only been studying C++ for a couple of months. Please help!
Thanks in advance.
Zeke
Standard C++ program follows:
// Purpose
// A program to demonstrate the application of a simple digital filter
//
// Overview
// A sequence of data items and digital filter values need to be entered by the
// user. The application of the filter to the data involves a simple convolution
// operation. The filtered data are stored separately.
//
// Example
// before filtering:
// data_in = [0 1 3 6 3 1 0]
// filter = [-0.5 1 -0.5]
// after filtering:
// data_out = [-0.5 -0.5 3 -0.5 -0.5]
// where
// data_out[0]=data_in[0]*filter[0]+data_in[1]*filter[1]+data_in[2]*filter[2]
// data_out[1]=data_in[1]*filter[0]+data_in[2]*filter[1]+data_in[3]*filter[2]
// data_out[2]=data_in[2]*filter[0]+data_in[3]*filter[1]+data_in[4]*filter[2]
// data_out[3]=data_in[3]*filter[0]+data_in[4]*filter[1]+data_in[5]*filter[2]
// data_out[4]=data_in[4]*filter[0]+data_in[5]*filter[1]+data_in[6]*filter[2]
//
// The program checks the following
// 1. The data and filter values must have been entered before the filter is
// applied
// 2. The filter is not applied if the number of filter values is greater than
// the number of input data values
// 3. The data and filter values must have been entered and the filter applied
// before the filtered data can be displayed
#include <iostream>
using namespace std;
// the data values and the filter
struct TheFilter {
double* Values; // the filter values
unsigned long Length; // number of filter values
bool Valid; // true if the filter values have been Valid by the user
};
struct TheData {
double* Values; // holds the data to be filtered
unsigned long Length; // number of data values
bool Valid; // true if the data values have been Valid by the user
};
// function return values
enum {OK,FILTER_TOO_LONG};
// function prototypes
void EnterData(TheData&);
void EnterFilter(TheFilter&);
int ApplyFilter(TheFilter, TheData, TheData&);
void DisplayData(TheFilter, TheData, TheData);
// Control the principal operations of the program
// Arguments: None
// Returns: 0 on completion
int main()
{
// define the filter and its initial values
TheFilter Filter = {0,0,false};
// define the original data and its initial values
TheData OriginalData = {0,0,false};
// define the filtered data and its initial values
TheData FilteredData = {0,0,false};
char UserInput;
// loop until the user wishes to exit
while (1) {
// show the menu of options
cout << endl;
cout << "Filter Menu" << endl;
cout << "-----------" << endl;
cout << "1. Enter data for filtering" << endl;
cout << "2. Enter filter values" << endl;
cout << "3. Apply filter" << endl;
cout << "4. Display filtered data" << endl;
cout << "5. Exit from the program" << endl << endl;
// get the user's choice
cout << "Enter your option: ";
cin >> UserInput;
cout << endl;
// act on the user's input
switch(UserInput) {
case '1':
EnterData(OriginalData);
FilteredData.Valid = false;
break;
case '2':
EnterFilter(Filter);
FilteredData.Valid = false;
break;
case '3':
if (Filter.Valid == true && OriginalData.Valid == true &&
FilteredData.Valid == false) {
if (ApplyFilter(Filter,OriginalData,FilteredData) == FILTER_TOO_LONG) {
cout << "The filter must not be longer than the data" << endl;
}
else {
FilteredData.Valid = true;
cout << "Filter applied" << endl;
}
}
break;
case '4':
if (Filter.Valid == true && OriginalData.Valid == true &&
FilteredData.Valid == true) {
DisplayData(Filter,OriginalData,FilteredData);
}
else {
cout << "Data have not yet been filtered" << endl;
}
break;
case '5':
delete [] Filter.Values;
delete [] OriginalData.Values;
delete [] FilteredData.Values;
return 0;
break;
default:
cout << "Invalid entry" << endl << endl;
break;
}
}
}
// Allow the user to enter the data to be filtered
// Arguments:
// (1) the structure containing the input data
// Returns: nothing
//
void EnterData(TheData& GetData)
{
// initialize the data structure that holds the data to be filtered, including getting
// the number of data values from the user
delete [] GetData.Values;
cout << "How many data values do you wish to enter: ";
cin >> GetData.Length;
GetData.Valid = true;
// allocate memory to the data
GetData.Values = new double[GetData.Length];
if (GetData.Values == 0) {
cout << "Unable to allocate sufficient memory" << endl;
exit(1);
}
// obtain all of the data values
cout << endl;
cout << "Enter the data values" << endl;
cout << "---------------------" << endl;
for (unsigned long CountData = 0; CountData < GetData.Length; CountData++) {
cout << "Enter value " << CountData+1 << ": ";
cin >> GetData.Values[CountData];
}
}
// Allow the user to enter the filter values
// Arguments:
// (1) the structure of the filter to be defined
// Returns: nothing
//
void EnterFilter(TheFilter& GetFilter)
{
// initialize the data structure that holds the filter, including getting the number of
// filter values from the user
delete [] GetFilter.Values;
cout << "How many data values do you wish to enter: ";
cin >> GetFilter.Length;
GetFilter.Valid = true;
// allocate memory to the filter values
GetFilter.Values = new double[GetFilter.Length];
if (GetFilter.Values == 0) {
cout << "Unable to allocate sufficient memory" << endl;
exit(1);
}
// obtain all of the filter values
cout << endl;
cout << "Enter the filter values" << endl;
cout << "-----------------------" << endl;
for (unsigned long CountData = 0; CountData < GetFilter.Length; CountData++) {
cout << "Enter value " << CountData+1 << ": ";
cin >> GetFilter.Values[CountData];
}
}
// Apply the filter to the input data and store in the filtered data structure
// Arguments:
// (1) the structure of the filter to be applied
// (2) the structure containing the data to be filtered
// (3) the structure to hold the filtered data
// Returns: OK - if the filter is applied
// FILTER_TOO_LONG - the filter is longer than the data
//
int ApplyFilter(TheFilter Filter, TheData DataIn, TheData& DataOut)
{
// return an error if the filter is longer than the data
if (Filter.Length > DataIn.Length) return FILTER_TOO_LONG;
// initialize the data structure that holds the filtered data
delete [] DataOut.Values;
DataOut.Length = DataIn.Length - Filter.Length + 1;
// get memory for the filtered data
DataOut.Values = new double[DataOut.Length];
if (DataOut.Values == 0) {
cout << "Unable to allocate sufficient memory" << endl;
exit(1);
}
// apply the filter to the data
for (unsigned long CountData = 0; CountData < DataOut.Length; CountData++) {
DataOut.Values[CountData] = 0.0;
for (unsigned long CountFilter = 0; CountFilter<Filter.Length; CountFilter++) {
DataOut.Values[CountData] += DataIn.Values[CountData+CountFilter] *
Filter.Values[CountFilter];
}
}
return OK;
}
// Display input data, filter values and output data
// Arguments:
// (1) the structure of the filter to be applied
// (2) the structure containing the data to be filtered
// (3) the structure that holds the filtered data
// Returns: nothing
//
void DisplayData(TheFilter Filter, TheData DataIn, TheData DataOut)
{
// display all of the input data values
cout << endl;
cout << "The input data values" << endl;
cout << "---------------------" << endl;
cout << "[ ";
for (unsigned long CountData = 0; CountData < DataIn.Length; CountData++) {
cout << DataIn.Values[CountData] << " ";
}
cout << "]" << endl;
// display all of the filter values
cout << endl;
cout << "The filter values" << endl;
cout << "-----------------" << endl;
cout << "[ ";
for (unsigned long CountData = 0; CountData < Filter.Length; CountData++) {
cout << Filter.Values[CountData] << " ";
}
cout << "]" << endl;
// display all of the data output values
cout << endl;
cout << "The data output values" << endl;
cout << "----------------------" << endl;
cout << "[ ";
for (unsigned long CountData = 0; CountData < DataOut.Length; CountData++) {
cout << DataOut.Values[CountData] << " ";
}
cout << "]" << endl;
}