版本24和25间的区别
于2006-11-18 23:06:03修订的的版本24
大小: 13089
编辑: czk
备注:
于2006-11-18 23:19:43修订的的版本25
大小: 14745
编辑: czk
备注:
删除的内容标记成这样。 加入的内容标记成这样。
行号 313: 行号 313:
                    cin >> item_type >> item_name >> item_value;                     cin >> item_type >> item_name;
                   getline(cin, item_value);
行号 362: 行号 363:
现在,添加的各种属性的值都能保存下来了。但是在查看详细信息的时候,还只有属性的名字,而没有属性的值。
行号 364: 行号 365:
显示联系人所有详细信息。为Item各种派生类添加to_string函数,比如:
{{{#!cplusplus
class DateItem : public Item{
    int year, month, day;
public:
    DateItem(string n, string value) :Item(n) {
        istringstream is(value);
        is >> year >> month >> day;
    }
    string to_string() {
        ostringstream os;
        os << get_name()<< " " << year << " " << month << " " << day;
        return os.str();
    }
};

class TextItem :public Item {
//......
    string to_string() {
        /*......*/
    }
};

class AddressItem :public Item {
//......
    string to_string() {
        /*......*/
    }
};

class PhoneItem :public Item {
//......
    string to_string() {
        /*......*/
    }
};

class NumericItem :public Item {
//......
    string to_string() {
        /*......*/
    }
};
}}}
为Item类添加虚函数to_string:
class Item {
//......
    virtual string to_string() {
        return name;
    }
};
}}}

修改main函数,把show中get_name改成to_string:
{{{#!cplusplus
//......
        if(command == "show") {
            string name;
            cin >> name;
            int i = list.find(name);
            if(i!=-1) {
                Contact *c = list.get(i);
                for(int j = 0; j < c->size(); j++) {
                    cout << c->get(j)->to_string() << endl;
                }
            }
        }
//......
}}}

TableOfContents

面向对象课程设计

1. 通讯录

数据定义:

  • 一个通讯录包含若干联系人的通讯信息
  • 每个联系人有姓名及其他自定义信息
  • 姓名:假定没有重复
  • 自定义信息:用户自己可以添加的信息字段,比如QQ,手机,生日等。自定义信息分为5类:电话、地址、日期、数字、文字。电话用于保存各种电话;日期用于保存年、月、日信息;地址包括国家、省份、城市、住址、邮编等信息;数字只能输入数字;文字可以输入任意文字。

功能说明:

  • 用户可以添加、修改、删除联系人
  • 用户可以显示所有联系人列表
  • 用户可以输入姓名,显示这个联系人的详细信息
  • 用户可以在各种自定义信息中查找联系人,并给出找到的所有联系人列表
  • 可以存盘和读盘

输入输出格式:程序以命令行方式交互式运行,命令包括:

  • list: 列出所有用户清单
  • show <name>: 列出某联系人的详细信息,name是联系人的名字,

  • add <name>: 添加指定的联系人,name是联系人的名字。新添加的联系人的名字与已有的联系人的名字不能重复。

  • remove <name>: 后面加联系人的名字,删除指定的联系人。

  • update <name> <action>: 修改联系人的信息,name是联系人的姓名,action可以是:

    • add <type> <attribute> <value>: 添加属性,attribute表示属性的名字,value表示属性的值,type表示属性的类型,可以是date、text、phone、numeric、address。

    • remove <attribute>: 删除属性,attribute表示属性的名字

    • update <attribute> <value>:更新属性的值

  • search <keyword>: 查找联系人,列出所有包含keyword的联系人

  • save <filename>: 将所有信息写入filename文件

  • load <filename>: 从filename中载入联系人信息

使用举例:

添加联系人,姓名叫做czk
 * add czk 
为czk添加属性mobile
 * update czk add phone mobile 13587654600  
为czk添加属性work
 * update czk add phone work 614600 
为czk添加属性qq
 * update czk add numeric qq 245149 
为czk添加属性birth
 * update czk add date birth 1979 8 27 
为czk添加属性email
 * update czk add text email czk@wzu.edu.cn 
添加联系人ymc
 * add ymc 
 * update ymc add phone mobile 13958895577
 * update ymc add phone work 665577
 * update ymc add text email jsj_ymc@wzu.edu.cn
显示所有的联系人
 * list 
显示czk的详细信息
 * show czk  
查找4600,应该可以找到czk
 * search 4600  
查找wzu.edu.cn,应该可以找到czk和ymc
 * search wzu.edu.cn 
把czk的email属性改为另一个值
 * update czk update email czk19790827@gmail.com 
删除czk的mobile属性
 * update czk remove mobile
将所有联系人存入contact.dat文件 
 * save contact.dat 
删除联系人ymc
 * remove ymc 
从contact.dat载入所有联系人信息(当前内存中的所有联系人被清空,替换成文件中所存储的联系人)
 * load contact.dat 

参考设计图:

  • attachment:OOPdesign1.png

1.1. 第一步

首先,做一个可以运行的主程序框架,可以接受输入各种指令,但是还不能实现任何功能。

   1 #include <iostream>
   2 #include <string>
   3 using namespace std;
   4 
   5 int main() {
   6     string command;
   7     string prompt = ">>> ";
   8     cout << prompt;
   9     while (cin >> command) {
  10         if(command == "list") {
  11 
  12         } else if(command == "show") {
  13 
  14         } else if(command == "add") {
  15 
  16         } else if(command == "remove") {
  17 
  18         } else if(command == "update") {
  19             
  20         } else if(command == "search") {
  21 
  22         } else if(command == "save") {
  23 
  24         } else if(command == "load") {
  25 
  26         } else if(command == "exit") {
  27             return 0;
  28         } else {
  29             cout << "Unknown command" << endl;
  30         }
  31         cout << prompt;
  32     }
  33 }

运行这个程序,输入正确命令不会有结果,输入错误命令提示Unknown command,输入exit退出程序。

1.2. 第二步

接下来为程序增加添加联系人和列出联系人清单的功能。先定义一个简单的Contact类:

   1 class Contact {
   2     string name; // the name of contact
   3 public:
   4     /** 初始化联系人名字为n*/
   5     Contact(string n) {
   6         /*......*/
   7     }
   8     /** 取联系人的名字 */
   9     string get_name() {
  10         /*......*/
  11     }
  12 
  13 };

然后定义ContactList类,实现添加联系人和取其中的联系人的功能

   1 class ContactList{
   2     Contact *contacts[100]; ///< 联系人数组
   3     int num; ///< 数组中的联系人总数
   4 public:
   5     /** 初始化列表为空表 */
   6     ContactList() {
   7         /*......*/
   8     }
   9     /** 在列表中添加一个名字叫做name的联系人 */
  10     void add(string name) {
  11         /*......*/
  12     }
  13     /** 取第i个联系人 */
  14     Contact* get(int i) {
  15         /*......*/
  16     }
  17     /** 列表中联系人总数 */
  18     int size() {
  19         /*......*/
  20     }
  21 };

最后修改main函数,使它可以完成添加、列出清单的功能

   1 int main() {
   2     ContactList list;
   3     //......
   4         if(command == "list") {
   5             for(int i = 0; i < contacts.size(); i++)
   6                 cout << list.get(i)->get_name() << endl;
   7         } else if(command == "add") {
   8             string name;
   9             cin >> name;
  10             list.add(name);
  11         }
  12     //......
  13 }

运行这个程序,可以完成add和list的功能

1.3. 第三步

为程序添加删除功能。为ContactList添加如下成员:

   1 //......
   2     /** 删除位置在第i个的联系人 */
   3     void remove(int i) {
   4         /*......*/
   5     }
   6     /** 查找名字是name的联系人,返回联系人的位置。找不到返回-1 */
   7     int find(string name) {
   8         /*......*/
   9     }
  10 
  11     /** 删除名字是name的联系人 */
  12     void remove(string name) {
  13         int i = find(name);
  14         if(i != -1)
  15             remove(i);                
  16     }
  17 //......
  18 

然后修改main函数:

   1 //......
   2         if(command == "remove") {
   3             string name;
   4             cin >> name;
   5             list.remove(name);
   6         }
   7 //......
   8 

运行这个程序,可以完成remove功能了。

1.4. 第四步

接下来,让程序可以为联系人添加属性。首先添加Item类:

   1 class Item {
   2     string name; ///<属性项的名字
   3 public:
   4     /// 初始化属性的名字是n
   5     Item(string n) {
   6         /*......*/
   7     }
   8     /// 获取属性的名字
   9     string get_name() {
  10         /*......*/
  11     }
  12 };

然后为Contact类添加成员:

   1 //......
   2     Item* items[100];
   3     int num;
   4 //......
   5     /// 添加属性项
   6     void add(Item *item) {
   7         items[num++] = item;
   8     }
   9     
  10     /// 添加类型是type,名字是name,值是value的属性项
  11     void add(string type, string name, string value) {
  12         add(new Item(name)); //这里暂时不区分类型,只是创建简单的Item类型对象添加进去
  13     }
  14     
  15     /// 属性项的总数
  16     int size() {
  17         /*......*/
  18     }
  19 
  20     /// 取某一项属性
  21     Item *get(int i) {
  22         /*......*/
  23     }
  24 //......
  25 

然后修改main函数,处理输入的update命令

   1         if(command == "update") {
   2             string name, subcommand, item_name, item_type, item_value;
   3             cin >> name;
   4             int i = list.find(name);
   5             if(i != -1) {
   6                 Contact *c =  list.get(i);
   7                 cin >> subcommand;
   8                 if(subcommand == "add") {
   9                     cin >> item_type >> item_name;
  10                     getline(cin, item_value);
  11                     c->add(item_type, item_name, item_value);
  12                 } else if (subcommand == "remove") {
  13                     
  14                 }
  15             }
  16         }

现在就可以运行程序,为联系人添加属性了。但是还不能看到添加进去的属性。

1.5. 第五步

为程序添加查看联系人详细信息的功能。

   1 //......
   2         if(command == "show") {
   3             string name;
   4             cin >> name;
   5             int i = list.find(name);
   6             if(i!=-1) {
   7                 Contact *c = list.get(i);
   8                 for(int j = 0; j < c->size(); j++) {
   9                     cout << c->get(j)->get_name() << endl;
  10                 }
  11             }            
  12         } 
  13 //......
  14 

运行程序,可以看到添加进去的属性的名字,但是还没有属性的值。

1.6. 第六步

删除联系人的属性。为Contact类添加成员:

   1     /// 删除联系人的第i个属性项
   2     void remove(int i) {
   3         /*......*/
   4     }
   5     /// 查找属性名字是n的编号,找不到返回-1
   6     int find(string n) {
   7         /*......*/
   8     }
   9     /// 删除属性名称是n的属性
  10     void remove(string n) {
  11         int i = find(n);
  12         if(i!=-1)
  13             remove(i);
  14     }

修改main函数

   1 //......
   2                 if(subcommand == "add") {
   3                     cin >> item_type >> item_name;
   4                     getline(cin, item_value);
   5                     c->add(item_type, item_name, item_value);
   6                 } else if (subcommand == "remove") {
   7                     cin >> item_name;
   8                     c->remove(item_name);
   9                 }
  10 //......
  11 

1.7. 第七步

添加各种不同类型的Item。定义Item的五个派生类

   1 class DateItem : public Item{
   2     int year, month, day;
   3 public:
   4     DateItem(string n, string value) :Item(n) {
   5         istringstream is(value);
   6         is >> year >> month >> day;
   7     }
   8 };
   9 
  10 class AddressItem : public Item {
  11 /*......*/
  12 };
  13 
  14 class PhoneItem : public Item {
  15 /*......*/
  16 };
  17 
  18 class NumericItem: public Item {
  19 /*......*/
  20 };
  21 
  22 class TextItem: public Item {
  23 /*......*/
  24 };

修改Contact的add函数:

   1 //......
   2     /// 添加类型是type,名称是name,值是value的属性
   3     void add(string type, string name, string value) {
   4         if(type == "date") {
   5             add(new DateItem(name, value);
   6         } else if(type == "phone")
   7             /*......*/
   8     }
   9 //......
  10 

现在,添加的各种属性的值都能保存下来了。但是在查看详细信息的时候,还只有属性的名字,而没有属性的值。

1.8. 第八步

显示联系人所有详细信息。为Item各种派生类添加to_string函数,比如:

   1 class DateItem : public Item{
   2     int year, month, day;
   3 public:
   4     DateItem(string n, string value) :Item(n) {
   5         istringstream is(value);
   6         is >> year >> month >> day;
   7     }
   8     string to_string() {
   9         ostringstream os;
  10         os << get_name()<< " " << year << " " << month << " " << day;
  11         return os.str(); 
  12     }
  13 };
  14 
  15 class TextItem :public Item {
  16 //......
  17     string to_string() {
  18         /*......*/
  19     }
  20 };
  21 
  22 class AddressItem :public Item {
  23 //......
  24     string to_string() {
  25         /*......*/
  26     }
  27 };
  28 
  29 class PhoneItem :public Item {
  30 //......
  31     string to_string() {
  32         /*......*/
  33     }
  34 };
  35 
  36 class NumericItem :public Item {
  37 //......
  38     string to_string() {
  39         /*......*/
  40     }
  41 };

为Item类添加虚函数to_string: class Item { //......

  • virtual string to_string() {
    • return name;
    }

}; }}}

修改main函数,把show中get_name改成to_string:

   1 //......
   2         if(command == "show") {
   3             string name;
   4             cin >> name;
   5             int i = list.find(name);
   6             if(i!=-1) {
   7                 Contact *c = list.get(i);
   8                 for(int j = 0; j < c->size(); j++) {
   9                     cout << c->get(j)->to_string() << endl;
  10                 }
  11             }            
  12         }
  13 //......
  14 

2. 个人财务软件

设计一个基于字符界面的个人财务软件,基本功能包括:

  1. 账户管理。包括:添加、删除、修改账户
    • 账户分为4类:资产、债务、收入、支出。
    • 资产账户是指个人所拥有的财产,比如现金、存款、借出款、股票等。
    • 债务账户是指个人所欠的债务,比如借入款,贷款等。
    • 支出账户是指个人的支出,比如交通、餐饮、购物、房租等
    • 收入账户是指个人的收入,比如工资、奖金、利息等
    • 每个资产账户和债务账户都有初始值。
  2. 交易管理(添加、删除交易,设置交易属性)
    • 交易用于完成在各个帐户之间的财务的转移,每笔记录有时间、转出账户、转入账户、金额、说明等属性。
    • 收入账户只能作为转出账户。支出账户只能作为转入账户。
  3. 统计功能
    • 统计各个资产账户和债务帐户的当前状况
    • 统计历史一段时间内的收入和支出状况
    • 统计一个账户的所有历史交易
  4. 存盘和读取
    • 所有操作能够自动存盘,下次打开程序时能够从磁盘读取,恢复到关闭程序前一样的状态。

使用举例:

刚开始使用可以设置如下账户:

  • 资产账户:现金、饭卡、招商银行卡、工商银行卡、借出
  • 债务账户:借入
  • 支出账户:交通支出、购物支出、吃饭支出
  • 收入账户:工资

每个资产账户和债务账户设置好初始值。然后开始记录每一笔交易:

  • 从家里到学校坐公交花去2元:新建交易,从现金转移到交通支出2元
  • 吃早饭,饭卡上花去4元:新建交易,从饭卡转移到吃饭支出4元
  • 从别人那里借了300元:新建交易,从借入账户转移300元到现金帐户
  • 发工资,工商银行卡多出1080元:新建交易,从工资帐户转移到工商银行卡1080元
  • 借给朋友现金200元:新建交易,从现金帐户转移到借出账户200元
  • 把借别人的300元还掉:新建交易,从现金转移300元到借入账户

3. 画板

设计一个图形编辑软件,基本功能包括:

  • 能够画点
  • 能够画直线
  • 能够画圆
  • 能够画圆弧
  • 能够写文字
  • 能够插入图像
  • 画面上的图形、文字、图像能够在画面上移动
  • 画面上的图形、文字、图像能够删除
  • 能够保存
  • 保存的画面能够打开,跟关闭前的画面一模一样

C++课程设计 (2008-02-23 15:36:45由localhost编辑)

ch3n2k.com | Copyright (c) 2004-2020 czk.