Question
write this c code. please modify the code (given below) to use more inheritance. As well, in this project, you will be asked to use
write this c code. please modify the code (given below) to use more inheritance. As well, in this project, you will be asked to use new and delete, throw and catch exceptions and also create / use virtual functions. More Types of Radios Create a new class called PioneerAM. This class will inherit from PioneerCarRadio. o PioneerAM behaves like PioneerCarRadio except that it operates in the AM band only! o There is no ability to change to the FM band they shouldnt even display the FM band o Do this by overriding the appropriate methods that are in the parent class or grandparent class. Create a new class called PioneerWorld. This class will inherit from PioneerAM. o PioneerWorld behaves like PioneerAM ? Except that the AM band range is 531 kHz to 1602 kHz ? And the interval between frequencies is 9 kHz, not 10 kHz ? So scanning up from 531 would bring you to 540, then 549, etc. Wrapping from 1602 brings you to 531. o Do this by overriding the appropriate methods that are in the parent class or grandparent class. New/Delete and Exceptions Create a new testHarness (i.e. your main()) and put it in a file called ultimateRadio.cpp. In this main o Change your PioneerCarRadio variable to be a pointer o Give it an initial value of NULL o Call this variable pRadio. When your program starts o You will need to create and call a function named createRadio() that takes a string (or char pointer your choice) to determine which type of radio you want to start with and returns a pointer to that radio back to main() and into the pRadio pointer. ? Your program will need to get this string (or char pointer) from the command line arguments of the program ? This means you needs to take in and parse command-line arguments ? This function will exist in the ultimateRadio.cpp file and when passed the string (or char pointer) will ? If the program is started with the runtime switch of car then instantiate a new PioneerCarRadio object and return it to assign it to pRadio. ? If the program is started with the runtime switch of am then instantiate a new PioneerAM object and return it to assign it to pRadio. ? If the program is started with the runtime switch of world then instantiate a new PioneerWorld object and return it to assign it to pRadio. ? Otherwise, throw an exception. ? Remember you will need to write this createRadio() function o Since it will be throwing exception(s), remember to put the call to createRadio() in a try block o Remember that you will initially be getting this functions parameter from a command line argument o In the catch clause, print an error message and quit the program o Make sure to instantiate each radio in an off state Whenever you use new, use the principles discussed in class to handle this correctly. o You are required to use the new new in this assignment o Use exception handling to detect out-of-memory situations Virtual Functions In order to implement these 2 new children classes, you will once again need to override some methods Make any overridden methods virtual in the parent class o Recommendations: ToggleFrequency(), ScanUp(), ScanDown(). Since we are using virtual functions, remember best practices and make all destructors virtual Switching Radios and Quitting the Program Each specialized radio class needs to tell the user who they are o The PioneerCarRadio already does with the Pioneer XS440 that appears in its output o Make the PioneerAM class say Pioneer XS440-AM o And the PioneerWorld class say Pioneer XS440-WRLD Create a destructor for each new class o In each destructor, simply print a message stating which radio is being destroyed o e.g. "Destroying Pioneer XS440-WRLD Radio" The output from PioneerCarRadio, PioneerAM and PioneerWorld is somewhat the same except for the difference in its name (i.e. the first line of output) and the presence/absence of the FM band o Try to think of a clever way to implement this radio name idea o Perhaps by adding a data member to one of the classes to hold the name hmmm Each radio instance that is created, will run until the 'x' key is pressed within that instance o This means that each of the Pioneer classes shares the same input processing ? As developed in Assign-03 o Once an x key is pressed, the radio object is destroyed in the ultimateRadio.cpp source o And do nothing until the user presses one of the following keys ? c -- to create and run a new PioneerCarRadio radio ? a -- to create and run a new PioneerAM radio ? w -- to create and run a new PioneerWorld radio ? x - to quit the program ? Note that these keystrokes will need to be captured and processed within your testHarness (where the new radio would be created) In Case It Makes Things Easier You can create mutators and accessors for whatever private data members you need to from the AmFmRadio class What Not To Do Don't put excessive amounts of the parent class's functionality (PioneerCarRadio) in the child classes (PioneerAM, PioneerWorld) unnecessarily o This is duplicating functionality and code a definite no-no Submitting the Assignment Put your new class definitions in PioneerAM.h and PioneerWorld.h o To make marking of this assignment easier, please put all method bodies for the new classes in the class definitions (even if the methods are more than a couple of lines) Do not create any other new .cpp files It is acceptable to change existing .cpp files and .h files or to create new .h files. Other Stuff As always, make sure that you place a classHeader comment at the start of each of the new classes as well as appropriate methodHeader and inline comments for the methods ZIP up all the source files : PioneerAM.h, PioneerWorld.h, PioneerCarRadio.cpp, PioneerCarRadio.h, AmfmRadio.cpp, AmfmRadio.h and ultimateRadio.cpp
//AmfmRadio.h
#ifndef _CARRADIO_H
#define _CARRADIO_H
struct Freqs
{
int AMFreq;
double FMFreq;
};
class AmFmRadio
{
private:
Freqs button[5];
Freqs old_station; // holds the old station when switching between AM and FM
double current_station;
char frequency[3];
int volume; int old_volume;
bool on;
bool displayOutput;
public:
//sets the each button to the lowest frequency, sets the current station, sets the
//frequency to AM, sets the volume to 0 and sets on to false
AmFmRadio(bool radioState = false);
//sets the each button to the lowest frequency, sets the current station, sets the
//frequency to AM, loads all frequencies, sets the volume to 0 and sets on to false
AmFmRadio(bool radioState, Freqs freqs[5]);
// display message on destruction
~AmFmRadio();
//sets on to true
void PowerToggle();
//returns a true if the radio is currently powered on, and false if the radio is in
//the off position
bool IsRadioOn();
//toggles frequency between AM and FM and sets current station
void ToggleFrequency();
//sets button with current station by being passed a button number
int SetButton(int button_num);
//sets current station by being passed a button number
int SelectCurrentStation(int button_num);
//sets volume
int SetVolume();
// sets volume that is passed as parameter
int SetVolume(int new_volume);
//shows volume, button settings, current station, AM or FM
void ShowCurrentSettings();
//changes frequency up in increments of .2 for FM, 10 for AM
void ScanUp();
// changes frequency down in decrements of .2 for FM, 10 for AM
void ScanDown();
// mutator for current_station
void SetCurrentStation(double new_station);
// mutator for controlling the output to screen
void ToggleOutput();
// accessor for current_station
double GetCurrentStation();
// accessor for current volume
int GetVolume();
// accessor for radio presets. accessed by passing array, that is filled
void GetButtons(Freqs export_buttons[5]);
// accessor for current band
char* GetBand();
// accessor for power state. Effectively a duplicate of IsRadioOn,
// added for naming consistency with other accessor methods
bool GetRadioPower();
// accessor for state of whether to display data to screen
bool GetDisplayOutput();
};
#endif
//AmPmRadio.cpp
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include "AmFmRadio.h"
/* -- Method Header Comment
Name : AmfmRadio -- CONSTRUCTOR
Purpose : It takes a single bool parameter that indicates whether the radio should be on or not when instantiated.
Give this parameter a default of false
Input : radioState bool(true or false) state of the radio either on or off/true or false(default)
Outputs : NONE
Returns : Nothing
*/
AmFmRadio::AmFmRadio(bool radioState)
{
for (int i = 0; i < 5; ++i)
{
button[i].AMFreq = 530;
}
for (int j = 0; j < 5; ++j)
{
button[j].FMFreq = 87.9;
}
current_station = 530;
old_station.AMFreq = 530; old_station.FMFreq = 87.9;
strcpy(frequency, "AM");
volume = 0; old_volume = 0;
on = radioState;
displayOutput = false;
}
/* -- Method Header Comment
Name : AmfmRadio -- CONSTRUCTOR
Purpose : It takes a single bool parameter that indicates whether the radio should be on or not when
instantiated and an array of 5 struct Freqs that contains the initial radio preset values
Input : radioState bool(true or false) state of the radio either on or off/true or false(default)
freqs freq an array of 5 struct freqs that contains the initial radio preset values
Outputs : NONE
Returns : Nothing
*/
AmFmRadio::AmFmRadio(bool radioState, Freqs freqs[5])
{
for (int i = 0; i < 5; ++i)
{
button[i].AMFreq = freqs[i].AMFreq;
}
for (int j = 0; j < 5; ++j)
{
button[j].FMFreq = freqs[j].FMFreq;
}
current_station = 530;
old_station.AMFreq = 530; old_station.FMFreq = 87.9;
strcpy(frequency, "AM");
volume = 0; old_volume = 0;
on = radioState;
displayOutput = false;
}
/* -- Method Header Comment
Name : AmfmRadio -- DESTRUCTOR
Purpose : to destroy the AmfmRadio object
Inputs : NONE
Outputs : outputs a final message from the object before being destroyed
Returns : Nothing
*/
AmFmRadio::~AmFmRadio()
{
if (displayOutput)
{
printf("Destroying AmFmRadio.");
}
}
/* -- Method Header Comment
Name : PowerToggle
Purpose : its used to reset volume if the power is off
Inputs : NONE
Outputs : NONE
Returns : Nothing
*/
void AmFmRadio::PowerToggle()
{
if (on == false)
{
on = true;
if (strcmp("AM", frequency) == 0)
{
current_station = old_station.AMFreq;
}
else
{
current_station = old_station.FMFreq;
}
// reset volume level
volume = old_volume;
}
else
{
on = false;
old_volume = volume;
// set volume to 0 if radio off
volume = 0;
}
}
/* -- Method Header Comment
Name : IsRadioOn
Purpose : It returns a true if the radio is currently powered on, and false if the radio is in the off position
Inputs : NONE
Outputs : NONE
Returns : Nothing
*/
bool AmFmRadio::IsRadioOn()
{
return on;
}
/* -- Method Header Comment
Name : SetVolume
Purpose : It enters the level of volume
Inputs : NONE
Outputs : it displays the volume level
Returns : Nothing
*/
int AmFmRadio::SetVolume()
{
char buf[20] = "";
printf(" Enter the volume level (0 - 100). ");
fgets(buf, sizeof buf, stdin);
volume = atoi(buf);
//if user enters volume less than 0, volume = 0
if (volume < 0)
{
volume = 0;
return 0;
}
//if user enters volume greater than 100, volume = 100
if (volume > 100)
{
volume = 100;
return 2;
}
return 1;
}
/* -- Method Header Comment
Name : SetVolume
Purpose : This addition is so that someone using SetVolume() can get the value in their own way and pass it to the method
Inputs : new_volume int it is use to pass in the volume value
Outputs : NONE
Returns : it returns an int
*/
int AmFmRadio::SetVolume(int new_volume)
{
if (new_volume < 0)
{
volume = 0;
return 0;
}
else if (new_volume > 100)
{
volume = 100;
return 2;
}
else
{
volume = new_volume;
}
return 1;
}
/* -- Method Header Comment
Name : ToggleFrequency
Purpose : Toggles frequency between AM and FM and sets current station
Inputs : NONE
Outputs : NONE
Returns : Nothing
*/
void AmFmRadio::ToggleFrequency()
{
if (strcmp(frequency, "AM") == 0)
{
strcpy(frequency, "FM");
old_station.AMFreq = current_station;
current_station = old_station.FMFreq;
}
else
{
strcpy(frequency, "AM");
old_station.FMFreq = current_station;
current_station = old_station.AMFreq;
}
}
/* -- Method Header Comment
Name : SetButton
Purpose : sets button with current station by being passed a button number
Inputs : button_num int
Outputs : NONE
Returns : it returns an int
*/
int AmFmRadio::SetButton(int button_num)
{
if ((button_num >= 0) && (button_num <= 4))
{
if (strcmp("AM", frequency) == 0)
{
button[button_num].AMFreq = current_station;
}
else
{
button[button_num].FMFreq = current_station;
}
return 1;
}
return 0;
}
/* -- Method Header Comment
Name : SelectCurrentStation
Purpose : Sets current station by being passed a button number
Inputs : NONE
Outputs : NONE
Returns : It returns current station an int
*/
int AmFmRadio::SelectCurrentStation(int button_num)
{
if ((button_num >= 0) && (button_num <= 4))
{
if (strcmp("AM", frequency) == 0)
{
current_station = button[button_num].AMFreq;
}
else
{
current_station = button[button_num].FMFreq;
}
return 1;
}
return 0;
}
/* -- Method Header Comment
Name : ShowCurrentSettings
Purpose : shows volume, button settings, current station, AM or FM
Inputs : NONE
Outputs : It prints out the volume, button settings, current station, AM or FM
Returns : Its shows current settings as a string
*/
void AmFmRadio::ShowCurrentSettings()
{
if (on == true)
{
printf(" Radio is on. ");
}
else
{
printf(" Radio is off. ");
}
printf(" Frequency: %s ", frequency);
printf("Volume: %d ", volume);
printf("Current Station: %.1f %s ", current_station, frequency);
printf("AM Button Settings: ");
for (int i = 0; i < 5; ++i)
{
printf("%d) %6d ", i + 1, button[i].AMFreq);
}
printf(" FM Button Settings: ");
for (int j = 0; j < 5; ++j)
{
printf("%d) %6.1f ", j + 1, button[j].FMFreq);
}
}
/* -- Method Header Comment
Name : ScanUp
Purpose : changes frequency up in increments of .2 for FM, 10 for AM
Inputs : NONE
Outputs : NONE
Returns : Nothing
*/
void AmFmRadio::ScanUp()
{
if (strcmp("AM", frequency) == 0)
{
//if current_station is 1700, the current_station becomes 530
if (current_station == 1700)
{
current_station = 530;
}
else
{
current_station = current_station + 10;
}
}
else
{
//if the current_station is 107.9, the current_station becomes 87.9
//Note: car radios jump .2 for the FM. That's how it's modeled here.
if (current_station >= 107.9)
{
current_station = 87.9;
}
else
{
current_station = current_station + .2;
}
}
if (displayOutput)
{
printf(" Current station: %f %s ", current_station, frequency);
}
}
/* -- Method Header Comment
Name : ScanDown
Purpose : changes frequency down in decrements of .2 for FM, 10 for AM
Inputs : NONE
Outputs : It display the current station
Returns : Nothing
*/
void AmFmRadio::ScanDown()
{
if (strcmp("AM", frequency) == 0)
{
//if current_station is 530, the current_station becomes 1700
if (current_station == 530)
{
current_station = 1700;
}
else
{
current_station = current_station - 10;
}
}
else
{
//if the current_station is 87.9, the current_station becomes 107.9
//Note: car radios jump .2 for the FM. That's how it's modeled here.
// to avoid problems with float precision
if (current_station <= 88.0)
{
current_station = 107.9;
}
else
{
current_station = current_station - .2;
}
}
if (displayOutput)
{
printf(" Current station: %f %s ", current_station, frequency);
}
}
/* -- Method Header Comment
Name : SetCurrentStation
Purpose : mutator for current station
Inputs : NONE
Outputs : NONE
Returns : Nothing
*/
void AmFmRadio::SetCurrentStation(double new_station)
{
if (strcmp("AM", frequency) == 0)
{
if (new_station < 530)
{
current_station = 530;
}
else if (new_station > 1700)
{
current_station = 1700;
}
else
{
current_station = new_station;
}
}
else
{
if (new_station < 87.9)
{
current_station = 87.9;
}
else if (new_station > 107.9)
{
current_station = 107.9;
}
else
{
current_station = new_station;
}
}
}
/* -- Method Header Comment
Name : ToggleOutput
Purpose : mutator for controlling the output to screen
Inputs : NONE
Outputs : NONE
Returns : Nothing
*/
void AmFmRadio::ToggleOutput()
{
if (displayOutput)
{
displayOutput = false;
}
else
{
displayOutput = true;
}
}
/* -- Method Header Comment
Name : GetCurrentStation
Purpose : Accessor for the radios current station
Inputs : NONE
Outputs : NONE
Returns : It returns the current station as a double
*/
double AmFmRadio::GetCurrentStation()
{
return current_station;
}
/* -- Method Header Comment
Name : GetVolume--Accessors
Purpose : Accessor for current volume
Inputs : NONE
Outputs : NONE
Returns : It returns the current volume as a int
*/
int AmFmRadio::GetVolume()
{
return volume;
}
/* -- Method Header Comment
Name : GetButtons--Accessors
Purpose : Accessor for radio presets. accessed by passing array, that is filled
Inputs : NONE
Outputs : NONE
Returns : nothing
*/
void AmFmRadio::GetButtons(Freqs export_buttons[5])
{
for (int i = 0; i < 5; i++)
{
export_buttons[i] = button[i];
}
}
/* -- Method Header Comment
Name : GetBand--Accessors
Purpose : Accessor for current band
Inputs : NONE
Outputs : NONE
Returns : It returns the current band as a string
*/
char * AmFmRadio::GetBand()
{
return frequency;
}
/* -- Method Header Comment
Name : GetRadioPower--Accessors
Purpose : Accessor for power state. Effectively a duplicate of IsRadioOn, added for naming consistency with other accessor methods
Inputs : NONE
Outputs : NONE
Returns : It returns true or false
*/
bool AmFmRadio::GetRadioPower()
{
return on;
}
/* -- Method Header Comment
Name : GetDisplayOutput--Accessors
Purpose : Accessor for state of whether to display data to screen
Inputs : NONE
Outputs : NONE
Returns : It returns true or false
*/
bool AmFmRadio::GetDisplayOutput()
{
return displayOutput;
}
//PioneerCarRadio.h
#include "AmFmRadio.h"
class PioneerCarRadio :
public AmFmRadio
{
public:
PioneerCarRadio();
~PioneerCarRadio();
// handle the controlling keystroke. if the keystroke represents valid action,
// print current state of radio
void ProcessKey(char key_val);
// display current state of radio. output is different depending on power of radio
void DisplayState();
};
//PioneerCarRadio.cpp
#include
#include
#include
#include "PioneerCarRadio.h"
/* -- Method Header Comment
Name : PioneerCarRadio -- CONSTRUCTOR
Purpose : Its purpose is to state the initial status of the car radio which is off(false)
Inputs : NONE
Outputs : NONE
Returns : Nothing
*/
PioneerCarRadio::PioneerCarRadio()
{
AmFmRadio(false);
}
/* -- Method Header Comment
Name : PioneerCarRadio -- destructor
Purpose : to destroy the PioneerCarRadio object
Inputs : NONE
Outputs : outputs a final message "Pioneer Car Radio destructed." from the object before being destroyed
Returns : Nothing
*/
PioneerCarRadio::~PioneerCarRadio()
{
printf("Pioneer Car Radio destructed.");
}
/* -- Method Header Comment
Name : ProcessKey
Purpose : it handles the controlling keystroke. if the keystroke represents valid action, print current state of radio
Inputs : key_val string It is used to entering valid keystroke values
Outputs : NONE
Returns : Nothing
*/
void PioneerCarRadio::ProcessKey(char key_val)
{
// to track whether to print state at the end of check
bool display = true;
switch (key_val)
{
case 'o':
{
PowerToggle();
break;
}
case '+':
{
int current_volume = GetVolume();
if (current_volume < 100) {
SetVolume(current_volume + 1);
};
break;
}
case '_':
{
int current_volume = GetVolume();
if (0 < current_volume) {
SetVolume(current_volume - 1);
};
break;
}
case '=':
{
ScanUp();
break;
}
case '-':
{
ScanDown();
break;
}
case 'b':
{
ToggleFrequency();
break;
}
case '1': case '2': case '3': case '4': case '5':
{
// if key_val is 1 to 5 this block will execute
// we use implicit type cast to get int from char.
int station_number_set = key_val - '1';
SelectCurrentStation(station_number_set);
break;
}
case '!': case '#': case '$': case '%':
{
// same logic. exception is that '@' isn't aligned with these 4 symbols
int station_number_choose = key_val - '!';
SetButton(station_number_choose);
break;
}
case '@':
{
SetButton(1);
break;
}
default:
// if no label was matched than wrong key was pressed
// suppress display in this case
display = false;
}
if (display)
{
DisplayState();
}
}
/* -- Method Header Comment
Name : DisplayState
Purpose : Its purpoe is to display current state of radio. output is different depending on power of radio
Inputs : NONE
Outputs : It displays the current state of the radio
Returns : Nothing
*/
void PioneerCarRadio::DisplayState()
{
if (GetRadioPower())
{
// print upper part of message
printf(" Pioneer XS440 ");
printf("Radio is on ");
printf("Volume: %d ", GetVolume());
printf("Current Station: %.1f %s ", GetCurrentStation(), GetBand());
// now print buttons
Freqs buttons[5];
// get buttons values
GetButtons(buttons);
printf("AM Buttons: ");
// i is 0 to 3 to avoid trailing comma and to add newline
for (int i = 0; i < 4; i++)
{
printf("%d: %d, ", i + 1, buttons[i].AMFreq);
}
printf("5: %d ", buttons[4].AMFreq);
// same for FM
printf("FM Buttons: ");
for (int i = 0; i < 4; i++)
{
printf("%d: %.1f, ", i + 1, buttons[i].FMFreq);
}
printf("5: %.1f ", buttons[4].FMFreq);
}
else
{
printf(" Pioneer XS440 Radio is off ");
}
}
//carDriver.cpp
#include
#include
#include
#include
#include "PioneerCarRadio.h"
int main()
{
PioneerCarRadio radio;
char option = ' ';
radio.DisplayState();
// Enter the inputs if the input isn't 'x' (running the input)
while (option != 'x')
{
// 'getch' did not work as well as '_getch'
// _getch return integer value of symbol, so i cast it to char
option = char(_getch());
radio.ProcessKey(option);
}
}
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started