170 likes | 318 Views
Classes: Implementation and Testing. Edited for CMPSC 122 Penn State University Prepared by Doug Hogan. Preview of Today…. Implementation Tips for implementing each kind of function More Examples Client end -- Test drivers. Review. Questions on the blue worksheet ?.
E N D
Classes: Implementation and Testing Edited for CMPSC 122 Penn State University Prepared by Doug Hogan
Preview of Today… • Implementation • Tips for implementing each kind of function • More Examples • Client end -- Test drivers
Review • Questions on the blue worksheet?
Implementing Functions • Remember • Implementation outside the class interface • Name of the class and scope resolution operator (::) before the FUNCTION NAME
Implementing Constructors • Do whatever is necessary to set up the class • Initialize each private member • Default constructors: • default values • Initializer constructors: • some from input parameters • validate? • set others to default values
Exercise Implement the default constructor for tvShow. tvShow::tvShow() { name = “New show”; channel = 2; startHour = 0; startMin = 0; }
Implementing initializer constructors • Most specify SOME, not ALL, initial values • Set the others as in the default constructor
name channel startHour startMin d Initializer constructor example tvShow::tvShow(string initName, int initChannel) { name = initName; // initialized from channel = initChannel; // parameters // we still need to handle two data members! startHour = 0; // initialized to startMin = 0; // defaults } tvShow object constructed with this method from init-Channel 0 0 value of initName
Implementing modifiers • Ultimately: must have assignment statements (or function calls) that change private data
Modifier Example void tvShow::reschedule(int hoursLater, int minutesLater) // PRE: hoursLater >= 0, 0 <= minutesLater <= 59 // POST: this tvShow now starts hoursLater hours and // minutesLater minutes after it did before { startHour = ((startMin + minutesLater)/60 + startHour + hoursLater)%24; // add on hour from minutes rolling over // add on hours, correct for day rolling over startMin = (startMin + minutesLater)%60; // add on time, correct for new hour }
Implementing Accessors • “Get” accessors • return a private variable • ex:int tvShow::getChannel() const{ return channel;} • Don’t forget the constif it’s in the prototype!
Accessors That Print vs. Accessors That Return • int tvShow::getChannel() const// POST: Method returns this show’s channel { return channel;} • void tvShow::printChannel() const// POST: Method displays this show’s channel { cout << "Channel: " << channel;} • Always provide the first type. The second type can be useful, but from a user interface design perspective, really ought to be avoided. A general principle is that you should separate logic from user interface at all times.
An Accessor Exercise • Write an accessor that prints the time of a tvShow in the format “8:30 a.m.”
An Accessor Exercise void tvShow::printTimeAMPM() const // POST: a string is displayed with this // show's start time in "h:mm a.m." form { int hr; // hour in format 1..12 hr = startHour%12; // get hour in 0..12 range if(hr == 0) // correct for hour 0 == 12 hr = 12; if(min <= 9) // need leading zero cout << hr << ":0" << min; else // no leading zero cout << hr << ":" << min; if(startHour < 12) // check for a.m. cout << " a.m."; else // otherwise it's p.m. cout << " p.m."; } Question: Can any of the if statements be optimized?
Test Drivers • Main program that checks whether the class is working properly • Create a few objects • Call each of the member functions • Check the results • Good practice: test drive classes before writing programs with them • Find the errors WITHIN THE CLASS vs. outside the class
Example Test Driver int main() { bankAccount acct1; // def. constructor bankAccount acct2("Homer", 100); // one init constr bankAccount acct3("Lisa"); // another init con acct1.resetAcct("Marge", 75); // test resetAcct cout << acct1.getName(); // test getName // did resetAcct work? cout << acct1.getBalance(); // test getBalance // did resetAcct work? acct1.deposit(50); // deposit cout << acct1.getBalance(); // did deposit work? acct1.withdraw(100); // withdraw cout << acct1.getBalance(); // did withdraw work? // additional calls, use accessors to see that other // constructors worked } Note: Comments in this test driver are for you. I'll never require test driver comments.
Summary • Implementation • Scope resolution operator and class name • Constructors – initialize each private member • Modifiers – change private members • Accessors – remember const, printing vs. returning • Test drive classes before using them • Lab time now: Your turn to make your own class!