
lafore_robert_objectoriented_programming_in_c
.pdf

826 |
Chapter 16 |
|
friend ostream& operator << (ostream&, const tenant&); |
||
|
||
|
||
|
}; // end class tenant |
|
|
///////////////////////class compareTenants///////////////////// |
|
|
class compareTenants //function object -- compares tenants |
|
|
{ |
|
|
public: |
|
|
bool operator () (tenant*, tenant*) const; |
|
|
}; |
|
|
////////////////////////class tenantList//////////////////////// |
|
|
class tenantList |
|
|
{ |
|
|
private: |
|
|
// set of pointers to tenants |
|
|
set<tenant*, compareTenants> setPtrsTens; |
|
|
set<tenant*, compareTenants>::iterator iter; |
public: |
|
~tenantList(); |
// destructor (deletes tenants) |
void insertTenant(tenant*); |
// put tenant on list |
int getAptNo(string); |
// return apartment number |
void display(); |
// display tenant list |
}; // end class tenantList |
|
/////////////////////class tenantInputScreen//////////////////// class tenantInputScreen
{
private:
tenantList* ptrTenantList; string tName;
int aptNo;
public:
tenantInputScreen(tenantList* ptrTL) : ptrTenantList(ptrTL) { /* empty */ }
void getTenant();
}; //end class tenantInputScreen
//////////////////////////class rentRow///////////////////////// // one row of the rent record: an address and 12 rent amounts class rentRow
{
private: int aptNo;
float rent[12];


Chapter 16
828
public:
rentInputScreen(tenantList* ptrTL, rentRecord* ptrRR) : ptrTenantList(ptrTL), ptrRentRecord(ptrRR)
{ |
/*empty*/ } |
|
|
void |
getRent(); |
//rent |
for one tenant and one month |
}; |
// end class rentInputScreen |
|
////////////////////////////class expense/////////////////////// class expense
{
public:
int month, day;
string category, payee; float amount;
expense()
{}
expense(int m, int d, string c, string p, float a) : month(m), day(d), category(c), payee(p), amount(a)
{ /*empty */ }
//needed for use in ‘set’
friend |
bool operator |
< (const expense&, const expense&); |
friend |
bool operator |
== (const expense&, const expense&); |
// needed for output |
|
|
friend |
ostream& operator << (ostream&, const expense&); |
|
}; // |
end class expense |
////////////////////////////////////////////////////////////////
class compareDates //function object--compares expenses
{
public:
bool operator () (expense*, expense*) const;
};
////////////////////////////////////////////////////////////////
class compareCategories //function object--compares expenses
{
public:
bool operator () (expense*, expense*) const;
};
////////////////////////class expenseRecord///////////////////// class expenseRecord
{
private:
// vector of pointers to expenses vector<expense*> vectPtrsExpenses; vector<expense*>::iterator iter;


Chapter 16
830
~userInterface(); void interact();
}; // end class userInterfac
//////////////////////////end file landlord.h//////////////////////
Class Declarations
Declaring classes is the easy part. Most class declarations arise directly from the classes discovered by examining the nouns in the use case descriptions and seen on the class diagram. The names are changed from the multi-word English versions to single-word computerese, so that, for example, Tenant List becomes tenantList.
A few new classes have been added. We’ll find that we’re storing pointers to objects in various kinds of STL containers. This means that we must define comparison objects for these containers, as described in Chapter 15, “The Standard Template Library.” These comparison objects are actually classes named compareTenants, compareRows, compareDates, and compareCategories.
Attribute Declarations
As we noted, many of the attributes (member data) for each class can be determined from nouns that weren’t used for classes. For example, name and aptNumber become attributes of the tenant class declaration.
Other attributes can be inferred from the associations in the class diagram. Associations may indicate attributes that are pointers or references to other classes. This is because you can’t associate with something if you can’t find it. Thus the rentInputScreen class has the attributes ptrTenantList and ptrRentRecord.
Aggregates
Aggregate associations are shown in three places on the class diagram. Often, aggregates indicate containers that are attributes of the containing class (the whole) holding objects (the parts).
Neither the use case descriptions nor the class diagram suggest what sort of container should be used for these aggregates. As a programmer, you’ll need to choose an appropriate container for each aggregate, whether it’s a simple array, an STL container, or something else. In LANDLORD, we made the following choices:
•The tenantList class contains an STL set of pointers to tenant objects.
•The rentRecord class contains a set of pointers to rentRow objects.
•The expenseRecord class contains a vector of pointers to expense objects.


832 |
Chapter 16 |
|
//-------------------------------------------------------------- |
|
char getaChar() |
// get a character |
{ |
|
char ch = cin.get(); |
|
cin.ignore(80, ‘\n’); |
|
return ch; |
|
} |
|
//-------------------------------------------------------------- |
|
/////////////////////methods for class tenant/////////////////// tenant::tenant(string n, int aNo) : name(n), aptNumber(aNo)
{ /* empty */ } //--------------------------------------------------------------
tenant::~tenant() { /* empty */ }
//--------------------------------------------------------------
int tenant::getAptNumber() { return aptNumber; }
//--------------------------------------------------------------
bool operator < (const tenant& t1, const tenant& t2) { return t1.name < t2.name; }
//--------------------------------------------------------------
bool operator == (const tenant& t1, const tenant& t2) { return t1.name == t2.name; }
//--------------------------------------------------------------
ostream& operator << (ostream& s, const tenant& t)
{ s << t.aptNumber << ‘\t’ << t.name << endl; return s; } //--------------------------------------------------------------
////////////////method for class tenantInputScreen//////////////
void tenantInputScreen::getTenant() |
//get tenant info |
|
{ |
|
|
cout << “Enter |
tenant’s name (George Smith): “; |
|
getaLine(tName); |
|
|
cout << “Enter |
tenant’s apartment number (101): “; |
|
cin >> aptNo; |
|
|
cin.ignore(80, |
‘\n’); |
//make tenant |
tenant* ptrTenant = new tenant(tName, aptNo); ptrTenantList->insertTenant(ptrTenant); //send to tenant list
}
////////////////////////////////////////////////////////////////
bool compareTenants::operator () (tenant* ptrT1, tenant* ptrT2) const
{ return *ptrT1 < *ptrT2; } //--------------------------------------------------------------


834 |
Chapter 16 |
|
//--------------------------------------------------------------
void rentRow::setRent(int m, float am)
{ |
rent[m] = am; } |
|
|
//-------------------------------------------------------------- |
|
|
|
float rentRow::getSumOfRow() |
// sum of rents in row |
||
{ |
return accumulate( &rent[0], &rent[12], 0); } |
||
//-------------------------------------------------------------- |
|
|
|
bool operator < (const rentRow& t1, const rentRow& t2) |
|||
{ return t1.aptNo < t2.aptNo; } |
|||
//-------------------------------------------------------------- |
|
|
|
bool operator == (const rentRow& t1, const rentRow& t2) |
|||
{ return t1.aptNo == t2.aptNo; } |
|||
//-------------------------------------------------------------- |
|
|
|
ostream& operator << (ostream& s, const rentRow& an) |
|||
{ |
|
|
|
s << an.aptNo << ‘\t’; |
//print apartment number |
||
for(int j=0; j<12; j++) |
//print 12 rents |
||
|
{ |
|
|
|
if(an.rent[j] |
== 0) |
|
|
s << “ 0 |
“; |
|
|
else |
|
|
|
s << an.rent[j] << “ |
“; |
}
s << endl; return s;
}
////////////////////////////////////////////////////////////////
bool compareRows::operator () (rentRow* ptrR1, rentRow* ptrR2) const
{ return *ptrR1 < *ptrR2; }
///////////////////methods for class rentRecord/////////////////
rentRecord::~rentRecord() |
//destructor |
{ |
|
while( !setPtrsRR.empty() ) |
//delete rent rows, |
{ |
//remove ptrs from set |
iter = setPtrsRR.begin(); |
|
delete *iter; |
|
setPtrsRR.erase(iter); |
|
} |
|
} |
|
//-------------------------------------------------------------- |
|
void rentRecord::insertRent(int aptNo, int month, float amount)
{ |
|
rentRow searchRow(aptNo); |
//temp row with same aptNo |
iter = setPtrsRR.begin(); |
//search setPtrsRR |