Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

lafore_robert_objectoriented_programming_in_c

.pdf
Скачиваний:
51
Добавлен:
27.03.2023
Размер:
8.94 Mб
Скачать

 

 

 

 

 

 

Object-Oriented Software Development

while( iter != setPtrsRR.end() )

 

 

 

 

 

 

{

 

 

 

 

 

 

if(searchRow==**iter)

 

 

//rentRow found?

{

 

 

 

 

//yes,

(*iter)->setRent(month, amount); //put rent in row

return;

 

 

 

 

 

 

}

 

 

 

 

 

 

else

 

 

 

 

 

 

iter++;

 

 

 

 

 

 

}

 

 

 

 

//didn’t find it

rentRow* ptrRow = new rentRow(aptNo);

//make new row

ptrRow->setRent(month, amount);

 

//put rent in row

setPtrsRR.insert(ptrRow);

 

 

//put row in vector

} // end insertRent()

 

 

 

 

 

//--------------------------------------------------------------

 

 

 

 

 

 

void rentRecord::display()

 

 

 

 

 

{

 

 

 

 

 

 

cout << “\nAptNo\tJan

Feb

Mar

Apr

May

Jun “

<<

“Jul

Aug

Sep

Oct

Nov

Dec\n”

<< “---------------------------------

 

 

 

 

 

<< “---------------------------------

 

 

 

 

 

\n”;

if( setPtrsRR.empty() )

 

 

 

 

 

cout << “***No rents***\n”;

 

 

 

else

 

 

 

 

 

 

{

 

 

 

 

 

 

iter = setPtrsRR.begin();

 

 

 

 

while( iter != setPtrsRR.end() )

 

 

cout << **iter++;

 

 

 

 

 

}

 

 

 

 

 

 

}

 

 

 

 

 

 

//--------------------------------------------------------------

 

 

 

 

 

 

float rentRecord::getSumOfRents()

// return sum of all rents

{

 

 

 

 

 

 

float sumRents = 0.0; iter = setPtrsRR.begin();

while( iter != setPtrsRR.end() )

{

sumRents += (*iter)->getSumOfRow(); iter++;

}

return sumRents;

}

//--------------------------------------------------------------

/////////////////methods for class rentInputScreen////////////// void rentInputScreen::getRent()

835

16

O D BJECT EVELOPMENT S

OFTWARE - RIENTEDO

836

Chapter 16

 

{

cout << “Enter tenant’s name: “; getaLine(renterName);

aptNo = ptrTenantList->getAptNo(renterName);

if(aptNo > 0)

// if name found,

{

// get rent amount

cout << “Enter amount paid (345.67): “;

cin >> rentPaid;

 

cin.ignore(80, ‘\n’);

 

cout << “Enter month rent is for (1-12): “;

cin >> month;

 

cin.ignore(80, ‘\n’);

 

month--;

// (internal is 0-11)

ptrRentRecord->insertRent(aptNo, month, rentPaid);

}

 

else

// return

cout << “No tenant with that name.\n”; } // end getRent()

//--------------------------------------------------------------

///////////////////methods for class expense//////////////////// bool operator < (const expense& e1, const expense& e2)

{

// compares dates

if(e1.month == e2.month)

// if same month,

return e1.day < e2.day;

// compare days

else

// otherwise,

return e1.month < e2.month;

// compare months

}

 

//--------------------------------------------------------------

 

bool operator == (const expense& e1, const expense& e2)

{ return e1.month == e2.month && e1.day == e2.day; }

//--------------------------------------------------------------

 

ostream& operator << (ostream& s, const expense& exp)

{

 

s << exp.month << ‘/’ << exp.day << ‘\t’ << exp.payee << ‘\t’ ;

s << exp.amount << ‘\t’ << exp.category << endl;

return s;

 

}

 

//--------------------------------------------------------------

 

////////////////////////////////////////////////////////////////

bool compareDates::operator () (expense* ptrE1, expense* ptrE2) const

{ return *ptrE1 < *ptrE2; } //--------------------------------------------------------------

Object-Oriented Software Development

////////////////////////////////////////////////////////////////

bool compareCategories::operator () (expense* ptrE1, expense* ptrE2) const

{ return ptrE1->category < ptrE2->category; } //--------------------------------------------------------------

//////////////////methods for class expenseRecord///////////////

expenseRecord::~expenseRecord()

//destructor

{

 

 

while( !vectPtrsExpenses.empty() )

//delete expense objects,

 

{

//remove ptrs from vector

 

iter = vectPtrsExpenses.begin();

 

 

delete *iter;

 

 

vectPtrsExpenses.erase(iter);

 

 

}

 

}

 

 

//--------------------------------------------------------------

 

 

void expenseRecord::insertExp(expense* ptrExp)

{ vectPtrsExpenses.push_back(ptrExp); }

//--------------------------------------------------------------

 

 

void expenseRecord::display()

 

{

 

 

cout << “\nDate\tPayee\t\tAmount\tCategory\n”

 

<< “----------------------------------------

\n”;

if( vectPtrsExpenses.size() == 0 )

 

 

cout << “***No expenses***\n”;

 

else

 

 

{

 

 

sort( vectPtrsExpenses.begin(),

// sort by date

 

vectPtrsExpenses.end(), compareDates() );

 

iter = vectPtrsExpenses.begin();

 

 

while( iter != vectPtrsExpenses.end() )

 

cout << **iter++;

 

 

}

 

}

 

 

//-----------------------------------------------------------

 

 

float

expenseRecord::displaySummary() // used by annualReport

{

 

 

float totalExpenses = 0;

//total, all categories

if( vectPtrsExpenses.size() == 0 )

 

 

{

 

 

cout << “\tAll categories\t0\n”;

 

 

return 0;

 

 

}

 

//

sort by category

 

837

16

O D BJECT EVELOPMENT S

OFTWARE - RIENTEDO

Chapter 16

838

sort( vectPtrsExpenses.begin(), vectPtrsExpenses.end(), compareCategories() );

// for

each

category, sum the entries

iter =

vectPtrsExpenses.begin();

string

tempCat

= (*iter)->category;

float sumCat =

0.0;

while(

iter

!=

vectPtrsExpenses.end() )

{

if(tempCat == (*iter)->category)

sumCat += (*iter)->amount;

// same category

else

 

{

// different category

cout << ‘\t’ << tempCat << ‘\t’ << sumCat << endl;

totalExpenses += sumCat;

// add previous category

tempCat = (*iter)->category;

 

sumCat = (*iter)->amount;

// add final amount

}

 

iter++;

 

} // end while

 

totalExpenses += sumCat;

// add final category

cout << ‘\t’ << tempCat << ‘\t’ << sumCat << endl;

return totalExpenses;

 

} // end displaySummary()

 

//-----------------------------------------------------------

 

//////////////methods for class expenseInputScreen////////////// expenseInputScreen::expenseInputScreen(expenseRecord* per) :

ptrExpenseRecord(per)

{ /*empty*/ } //-----------------------------------------------------------

void expenseInputScreen::getExpense()

{

int month, day;

string category, payee; float amount;

cout << “Enter month (1-12): “; cin >> month;

cin.ignore(80, ‘\n’);

cout << “Enter day (1-31): “; cin >> day;

cin.ignore(80, ‘\n’);

cout << “Enter expense category (Repairing, Utilities): “; getaLine(category);

Object-Oriented Software Development

cout << “Enter payee “

<< “(Bob’s Hardware, Big Electric Co): “; getaLine(payee);

cout << “Enter amount (39.95): “; cin >> amount;

cin.ignore(80, ‘\n’); expense* ptrExpense = new

expense(month, day, category, payee, amount); ptrExpenseRecord->insertExp(ptrExpense);

}

//-----------------------------------------------------------

//////////////////methods for class annualReport///////////// annualReport::annualReport(rentRecord* pRR,

expenseRecord* pER) :

 

ptrRR(pRR), ptrER(pER)

{ /* empty*/ }

 

//-----------------------------------------------------------

 

void annualReport::display()

 

{

 

cout << “Annual Summary\n--------------

\n”;

cout << “Income\n”;

 

cout << “\tRent\t\t”;

 

rents = ptrRR->getSumOfRents();

 

cout << rents << endl;

 

cout << “Expenses\n”;

expenses = ptrER->displaySummary();

cout << “\nBalance\t\t\t” << rents - expenses << endl;

}

//-----------------------------------------------------------

////////////////methods for class userInterface////////////// userInterface::userInterface()

{

//these reports exist for the life of the program

ptrTenantList

= new tenantList;

ptrRentRecord

=

new rentRecord;

ptrExpenseRecord

=

new expenseRecord;

}

 

 

//-----------------------------------------------------------

userInterface::~userInterface()

{

delete ptrTenantList; delete ptrRentRecord; delete ptrExpenseRecord;

}

839

16

O D BJECT EVELOPMENT S

OFTWARE - RIENTEDO

Chapter 16

840

//-----------------------------------------------------------

void userInterface::interact()

{

while(true)

{

cout << “Enter ‘i’ to input data, \n”

<<“ ‘d’ to display a report, \n”

<<“ ‘q’ to quit program: “;

ch = getaChar();

 

if(ch==’i’)

// enter data

{

 

cout << “Enter ‘t’ to add tenant, \n”

 

<<“ ‘r’ to record rent payment, \n”

<<“ ‘e’ to record expense: “;

ch = getaChar(); switch(ch)

{

//input screens exist only while being used case ‘t’: ptrTenantInputScreen =

new tenantInputScreen(ptrTenantList); ptrTenantInputScreen->getTenant(); delete ptrTenantInputScreen;

break;

case ‘r’: ptrRentInputScreen =

new rentInputScreen(ptrTenantList, ptrRentRecord); ptrRentInputScreen->getRent();

delete ptrRentInputScreen; break;

case ‘e’: ptrExpenseInputScreen =

new expenseInputScreen(ptrExpenseRecord); ptrExpenseInputScreen->getExpense(); delete ptrExpenseInputScreen;

break;

default: cout << “Unknown input option\n”; break;

} // end switch

}// end if

else if(ch==’d’) // display data

{

cout << “Enter ‘t’ to display tenants, \n”

<<“ ‘r’ to display rents\n”

<<“ ‘e’ to display expenses, \n”

<<“ ‘a’ to display annual report: “; ch = getaChar();

switch(ch)

{

Object-Oriented Software Development

case ‘t’: ptrTenantList->display(); break;

case ‘r’: ptrRentRecord->display(); break;

case ‘e’: ptrExpenseRecord->display(); break;

case ‘a’:

ptrAnnualReport = new annualReport(ptrRentRecord, ptrExpenseRecord);

ptrAnnualReport->display(); delete ptrAnnualReport; break;

default: cout << “Unknown display option\n”; break;

}// end switch

}// end elseif else if(ch==’q’)

return;

//

quit

else

 

 

cout << “Unknown option. Enter only ‘i’,

‘d’ or ‘q’\n”;

} // end while

}// end interact()

///////////////////end of file landlord.cpp/////////////////////

More Simplifications

The code we show for LANDLORD, while quite lengthy, still contains many simplifications. It uses a character-mode user interface, not the menus and windows of a modern Graphic User Interface. There’s very little error-checking for the user’s input. Only one year’s worth of data can be handled.

Interacting with the Program

After going to the trouble to design and write the LANDLORD program, you may be interested in seeing some sample interaction with it. Here’s how it looks when Beverly uses it to insert a new tenant’s name and apartment number. First she enters ‘i’ followed by ‘t’, for “insert tenant.” Then she enters the relevant data at the prompts. (The prompts often show the proper format in parentheses.)

Enter ‘i’ to

input data,

‘d’ to

display a report,

‘q’ to

quit program: i

Enter ‘t’ to

add a tenant,

‘r’ to

record a rent payment,

‘e’ to

record an expense: t

841

16

O D BJECT EVELOPMENT S

OFTWARE - RIENTEDO

Chapter 16

842

Enter tenant’s name (George Smith): Harry Ellis

Enter tenant’s apartment number: 101

After she’s entered all the tenants, she can display the tenant list (for brevity we show only five of the twelve tenants):

Enter ‘i’ to

input data,

 

‘d’ to

display

a report,

 

‘q’ to

quit program: d

Enter ‘t’ to

display tenants,

 

‘r’ to

display

rents,

 

‘e’ to

display

expenses,

 

‘a’ to display

annual report: t

Apt#

Tenant name

 

--------------------

 

101Harry Ellis

102Wanda Brown

103Peter Quan

104Bill Vasquez

201Jane Garth

To input a rent paid by a tenant, Beverly enters ‘i’, then ‘r’. (From now on we’ll leave out the option lists displayed by the program.) The interaction looks like this:

Enter tenant’s name: Wanda Brown

Enter amount paid (345.67): 595

Enter month rent is for (1-12): 5

Here Wanda Brown has sent a check for the May rent in the amount of $595. (The tenant’s name must be typed exactly as it appears in the tenant list. A smarter program would be more flexible.)

To see the entire Rent Record, Beverly types ‘d’ followed by ‘r’. Here’s the result after the May rents have been received (for brevity we show the rents for only five of Beverly’s 12 units):

AptNo Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec

-----------------------------------------------------------------

101

695

695

695

695

695

0

0

0

0

0

0

0

102

595

595

595

595

595

0

0

0

0

0

0

0

103

810

810

825

825

825

0

0

0

0

0

0

0

104

645

645

645

645

645

0

0

0

0

0

0

0

201

720

720

720

720

720

0

0

0

0

0

0

0

Notice that Beverly raised Peter Quan’s rent in March.

Object-Oriented Software Development

To input an expense, Beverly types ‘i’ followed by ‘e’. Here’s some sample interaction:

Enter month: 1

Enter day: 15

Enter expense category (Repairing, Utilities): Utilities

Enter payee (Bob’s Hardware, Big Electric Co): P. G. & E.

Enter amount: 427.23

To display the Expense Report, you type ‘d’ and ‘e’. Here we show only the beginning of the report:

Date Payee Amount Category

------------------------------------------

1/3

First

MegaBank

5187.30

Mortgage

1/8

City Water

963.10

Utilities

1/9

Steady State

4840.00

Insurance

1/15

P. G. & E.

727.23

Utilities

1/22

Sam’s Hardware

54.81

Supplies

1/25

Ernie Glotz

150.00

Repairs

2/3

First MegaBank

5187.30

Mortgage

To display the Annual Report, Beverly enters ‘d’ and ‘a’. Here’s a partial version, covering the first five months of the year:

Annual Summary

 

--------------

 

Income

 

Rents

42610.12

Expenses

 

Advertising

95.10

Insurance

4840.00

Mortgage

25936.57

Repairs

1554.90

Supplies

887.22

Utilities

7636.15

Balance

1660.18

The expense categories are sorted in alphabetical order. In a real situation there would be many more budget categories, including legal fees, taxes, travel expenses, landscaping, cleaning and maintenance costs, and so on.

Final Thoughts

In a real project of any size, the development process would probably not go as smoothly as we’ve portrayed it in this chapter. Several iterations of each of the phases we’ve shown would be necessary. Programmers may find themselves confused about what the users intended, requiring a return to the elaboration phase while in the midst of the construction phase. Users may change their minds about what they want late in the process, requiring a return to earlier phases.

843

16

O D BJECT EVELOPMENT S

OFTWARE - RIENTEDO

Chapter 16

844

Summary

Trial and error may be sufficient for simple software development. For complex projects, a more organized approach is usually necessary. In this chapter, we’ve shown one possible methodology. The Unified Process consists of inception, elaboration, construction, and transition phases. Elaboration corresponds to program analysis, and construction corresponds to design and writing code.

The Unified Process uses the use case approach to capture the program’s users (actors) and the tasks (use cases) they want the program to carry out. A UML use case diagram shows the actors and use cases. From the use case descriptions, any noun is a candidate to become a class or a class attribute. Verbs become class member functions (also called operations or methods).

In addition to the use case diagram, other UML diagrams help to facilitate understanding between a program’s users and its developers. Relationships among classes can be shown in a class diagram, flow of control from one activity to another can be shown in activity diagrams, and sequence diagrams depict the communication between objects during the course of a use case.

Questions

Answers to these questions can be found in Appendix G.

1.True or false: the use case approach is concerned primarily with which methods a class uses.

2.Use cases are used to (among other things)

a.summarize problems encountered in program code.

b.discover what constructors a class may have.

c.help select appropriate class attributes.

d.deduce what classes may be necessary in a program.

3.A use case is basically a ________.

4.True or false: After a use case diagram is created, new use cases can be added after coding has begun.

5.A use case description is sometimes written in two ____________ .

6.An actor might be

a.a different system that interacts with the system being developed.

b.a software entity that helps the developer solve a particular coding problem.

c.a person who interacts with the system being developed.

d.the designer of the system.