面向对象软件开发:公寓财务管理系统实现
立即解锁
发布时间: 2025-08-19 01:36:38 阅读量: 1 订阅数: 6 


C++面向对象编程入门与实践
### 面向对象软件开发:公寓财务管理系统实现
#### 1. 开发阶段与迭代
在软件开发中,细化阶段确定的用例可转化为构建阶段的迭代。在大型项目里,每个迭代可能由不同的程序员团队负责。每个迭代可单独开发,再反馈给用户以确定变更或改进。不过,对于小型程序而言,无需如此复杂。
#### 2. 头文件(.H 文件)
编码的最佳起点是 .H 文件,在此定义类接口,而非具体的实现细节。.H 文件中的声明是类的公共部分,是类用户可见的部分;而 .CPP 文件中的函数体则是实现部分,对类用户应不可见。以下是 `LANDLORD.H` 文件的代码:
```cpp
//landlord.h
//header file for landlord.cpp -- contains class declarations, etc.
#pragma warning (disable:4786) //for set (microsoft only)
#include <iostream>
#include <vector>
#include <set>
#include <string>
#include <algorithm> //for sort()
#include <numeric> //for accumulate()
using namespace std;
//////////////////////////global methods///////////////////////
void getaLine(string& inStr); // get line of text
char getaChar(); // get a character
///////////////////////////class tenant/////////////////////////
class tenant
{
private:
string name; // tenant’s name
int aptNumber; // tenant’s apartment number
// other tenant information (phone, etc.) could go here
public:
tenant(string n, int aNo);
~tenant();
int getAptNumber();
// needed for use in ‘set’
friend bool operator < (const tenant&, const tenant&);
friend bool operator == (const tenant&, const tenant&);
// for I/O
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];
public:
rentRow(int); // 1-arg ctor
void setRent(int, float); // record rent for one month
float getSumOfRow(); // return sum of rents in row
// needed to store in ‘set’
friend bool operator < (const rentRow&, const rentRow&);
friend bool operator == (const rentRow&, const rentRow&);
// for output
friend ostream& operator << (ostream&, const rentRow&);
}; // end class rentRow
////////////////////////////////////////////////////////////////
class compareRows //function object -- compares rentRows
{
public:
bool operator () (rentRow*, rentRow*) const;
};
/////////////////////////class rentRecord///////////////////////
class rentRecord
{
private:
// set of pointers to rentRow objects (one per tenant)
set<rentRow*, compareRows> setPtrsRR;
set<rentRow*, compareRows>::iterator iter;
public:
~rentRecord();
void insertRent(int, int, float);
void display();
float getSumOfRents(); // sum all rents in record
}; // end class rentRecord
/////////////////////////class rentInputScreen//////////////////
class rentInputScreen
{
private:
tenantList* ptrTenantList;
rentRecord* ptrRentRecord;
string renterName;
float rentPaid;
int month;
int aptNo;
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;
public:
~expenseRecord();
void insertExp(expense*);
void display();
float displaySummary(); // used by annualReport
}; // end class expenseRecord
/////////////////////class expenseInputScreen///////////////////
class expenseInputScreen
{
private:
expenseRecord* ptrExpenseRecord;
public:
expenseInputScreen(expenseRecord*);
void getExpense();
}; // end class expenseInputScreen
///////////////////////class annualReport///////////////////////
class annualReport
{
private:
rentRecord* ptrRR;
expenseRecord* ptrER;
float expenses, rents;
public:
annualReport(rentRecord*, expenseRecord*);
void display();
}; // end class annualReport
///////////////////////class userInterface//////////////////////
class userInterface
{
private:
tenantList* ptrTenantList;
tenantInputScreen* ptrTenantInputScreen;
rentRecord* ptrRentRecord;
rentInputScreen* ptrRentInputScreen;
expenseRecord* ptrExpenseRecord;
expenseInputScreen* ptrExpenseInputScreen;
annualReport* ptrAnnualReport;
char ch;
public:
userInterface();
~userInterface();
void interact();
}; // end class userInterfac
//////////////////////////end file landlord.h//////////////////////
```
#### 3. 类声明
声明类相对容易。大多数类声明直接源于用例描述中通过分析名词发现的类,以及类图中呈现的类。类名会从多词的英文版本转换为单词的计算机术语,例如,“Tenant List” 变为 “tenantList”。同时,添加了一些新类。由于要在各种 STL 容器中存储对象指针,所以必须为这些容器定义比较对象,如 `compareTenants`、`compareRows`、`compareDates` 和 `compareCategories` 类。
#### 4. 属性声明
每个类的许多属性(成员数据)可由未用于类名的名词确定。例如,`name` 和 `aptNumber` 成为 `tenant` 类声明的属性。其他属性可从类图中的关联推断得出,关联可能表示指向其他类的指针或引用属性。例如,`rentInputScreen` 类具有 `ptrTenantList` 和 `ptrRentRecord` 属性。
#### 5. 聚合
类图中有三处显示了聚合关联。通常,聚合表示包含类(整体)的属性容器,用于容纳对象(部分)。用例描述和类图并未指明这些聚合应使用何种容器,作为程序员,需要为每个聚合选择合适的容器,如简单数组、STL 容器或其他类型。在 `LANDLORD` 中,做出了以下选择:
| 类名 | 容器选择 | 原因 |
| ---- | ---- | ---- |
| `tenantList` | STL set 存储 `tenant` 对象指针 | 提供快速访问 |
| `rentRecord` | set 存储 `rentRow` 对象指针 | 提供快速访问 |
| `expenseRecord` | vector 存储 `expense` 对象指针 | 需要按日期和类别对 `Expense` 对象进行排序,vector 可高效排序 |
在所有聚合中,选择存储指针而非实际对象,以避免每次存储实际对象时发生的复制操作。在对象较小且数量不多的情况下,直接存储对象可能是合适的。不过,为提高效率,应始终考虑存储指针。
#### 6. .CPP 文件
.CPP 文件包含在 .H 文件中声明的方法体。此时编写这些方法的代码应较为直接,因为已知函数名、其功能以及可能传递的参数。以下是 `LORDAPP.CPP` 文件的代码:
```cpp
// lordApp.cpp
// client file for apart program
#include “landlord.h”
int main()
{
userInterface theUserInterface;
theUserInterface.interact();
return 0;
}
////////////////////////end file lordApp.cpp////////////////////
```
以下是 `LANDLORD.CPP` 文件的代码,包含所有类方法的定义:
```cpp
//landlord.cpp
//models the finances for an apartment building
#i
```
0
0
复制全文
相关推荐










