Background: The purpose of this assignment is to practice dealing with exception
ID: 3760673 • Letter: B
Question
Background:
The purpose of this assignment is to practice dealing with exception handling and textual data. Exception handling is a very important part of being an object-oriented programming. Rather returning some kind of int return value every time you tickle an object, C++ programmers expect methods to focus on their task at hand. If something bad happens, C++ programmers expect methods to throw exceptions. When caught, exceptions can be processed. When uncaught, they cause a program to terminate dead in its tracks. The typical pattern in this course is to have class code throw exceptions and driver code catch them. Because of exceptions, when writing client driver code, our try blocks will not be polluted with error processing statements. Our other topic in this unit is recursion. I am trying to give you an assignment where you get some practice thinking recursively.
Project 1: Exception Mailbox
The purpose of this assignment is to work with exceptions. As you may recall, I have provided you with a sample class named Mailbox which has been diagrammed below. I'd like you to enhance this class so that invoking its methods or operators potentially throw exceptions, rather than just printing error messages to cout. Currently, our favorite exception class is std::logic_error. You can create a logic_error by passing a string value to its constructor. Officially, you should also say #include <stdexcept> to begin working with logic_error, but Visual Studio (being a badly behaved child...) let's you get away with it.
Although the sample driver code might not code for all these circumstances, I would like you to throw exceptions whenever:
a negative number is potentially stored in myContents (due to calls to operator - or negative values being sent to deliverMail)
a negative number is potentially stored in mySize (due to calls to operator - or setSize)
having a myContents that exceeds mySize (due to calls to operator + or deliverMail or setSize)
So carefully wind your way thru all the operators and methods of the class ensuring that logic_error gets thrown in each of these circumstances.
HINT: Recall that you can create a logic_error by passing a string message. For example,
std::logic_error error( "Bad News" );
While not required with Visual Studio, please #include <stdexcept> when working with this class. Linux fans will require this include; its optional for Windows users but wont hurt anything if you do it. Here is a class diagram for logic_error. As I said, it already exists so please make use of it.
Project 2: Adder
The goal of this program is to practice using recursion. The Adder class performs the mathematical operation a + b in two ways: one is iterative (using loops or control flow) and one is recursive (gets to call itself over and over again). You might not think that addition can be implemented using recursion, but if you follow the cases shown below, it can be done recursively:
BASE CASE: if ( a == 0 ) return( b );
BASE CASE: if ( b == 0 ) return( a );
RECURSIVE CASE: return( 2 + RecursiveAPlusB( a - 1, b -1 ) );
HINT: You'll probably need to create some additional methods...
Explanation / Answer
class TDriver: public HandleObject {
public:
// Constructor and destructor.
TDriver();
~TDriver();
OSErr iacOpen(ParmBlkPtr oParmBlock);
OSErr iacPrime(ParmBlkPtr pParmBlock);
OSErr iacControl(ParmBlkPtr cntlParmBlock);
OSErr iacStatus(ParmBlkPtr sParmBlock);
OSErr iacClose(ParmBlkPtr cParmBlock);
private:
short RegisterApp(IACRecord *anIACPtr);
short SendMessage(IACRecord *anIACPtr);
short ReceiveMessage(IACRecord *anIACPtr);
short UnregisterApp(IACRecord *anIACPtr);
void WhosThere(IACRecord *anIACPtr);
Boolean AnyMessagesForMe(IACRecord *anIACPtr);
TMessPtr GetMessage(short signature);
void SetMessage(short index, TMessPtr aMsgPtr);
char *GetAppName(short signature);
void SetAppName(short signature, char *anAppName);
char fAppNameArray[kMaxApps] [255];
TMessPtr fMessageArray[kMaxMessages];
};
from TMessage.h
class TMessage {
public:
TMessage(char *message, short senderSig, short receiverSig);
~TMessage();
Boolean IsMessageForMe(short sigOfRequestor);
Boolean IsMessageForMe(short sigOfRequestor, short *senderSig,
char *messageString);
private:
short GetSenderSig();
void SetSenderSig(short signature);
short GetReceiverSig();
void SetReceiverSig(short signature);
char *GetMessageString();
void SetMessageString(char *msgString);
short fSenderSig;
short fReceiverSig;
char fMessageString[255];
};
short
TDriver::RegisterApp(IACRecord *anIACPtr)
{
short i = 0;
short canDo = kNoMore;
while ((i < kMaxApps) && (canDo == kNoMore))
{
if((this->GetAppName(i))[0] == kZeroChar)
{
canDo = kNoErr;
anIACPtr->mySignature = i;
this->SetAppName(i,anIACPtr->appName);
}
i++;
}
return (canDo);
} // TDriver::RegisterApp
short
TDriver::SendMessage(IACRecord *anIACPtr)
{
TMessPtr aMsgPtr;
short canDo = kNoMore;
short i = 0;
aMsgPtr = new TMessage(anIACPtr->messageString,
anIACPtr->mySignature, anIACPtr->partnerSig);
if(aMsgPtr)
{
while ((i < kMaxMessages) && (canDo == kNoMore))
{
if(this->GetMessage(i) == nil)
{
this->SetMessage(i, aMsgPtr);
canDo = kNoErr;
}
i++;
}
if (canDo == kNoMore)
delete aMsgPtr;
} // if aMsgPtr
else
canDo = kMsgMemErr;
return (canDo);
} // TDriver::SendMessage
short
TDriver::ReceiveMessage(IACRecord *anIACPtr)
{
TMessPtr aMsgPtr;
short sender;
char *bufP = nil;
if(this->AnyMessagesForMe(anIACPtr))
{
aMsgPtr = this->GetMessage(anIACPtr->actualCount);
(void) aMsgPtr->IsMessageForMe
(anIACPtr->mySignature,&sender,bufP);
anIACPtr->partnerSig = sender;
tseStrCpy(anIACPtr->messageString,bufP);
tseStrCpy(anIACPtr->appName,
this->GetAppName(anIACPtr->partnerSig));
this->SetMessage(anIACPtr->actualCount,nil);
delete aMsgPtr;
return (kYesMessagesForMe);
}
else
return(kNoMore);
} // TDriver::ReceiveMessage
short
TDriver::UnregisterApp(IACRecord *anIACPtr)
{
char zeroChar = kZeroChar;
// Gotta delete those suckers.
while (this->ReceiveMessage(anIACPtr) == kYesMessagesForMe) ;
// Zero the name so others can play.
this->SetAppName(anIACPtr->mySignature,&zeroChar);
return (kNoErr);
} // TDriver::UnregisterApp
void
changeDRVRSlot(short slot)
{
Handle theDRVR;
short err, refNum;
char *name, DRVRname[256];
short DRVRid;
ResType DRVRType;
name = "p.TimDriver";
if(slot != 0) {
theDRVR = GetNamedResource('DRVR', name);
GetResInfo(theDRVR, &DRVRid, &DRVRType, &DRVRname);
SetResInfo(theDRVR, slot, 0L);
err = OpenDriver(name, &refNum);
if(err == noErr)
{
/* Detach the resources from the resource map. */
DetachResource(theDRVR);
}
theDRVR = GetNamedResource('DRVR', name);
SetResInfo(theDRVR, DRVRid, nil);
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.