- 设计快捷店会员的简单管理程序。基本要求如下:
(1)定义人民币RMB类,实现人民币的基本运算和显示。
(2)定义会员member类,表示会员的基本信息,包括:编号(按建立会员的顺序自动生成),姓名,密码,电话。提供输入、输出信息等功能。
(3)由RMB类和member类共同派生一个会员卡memberCar类,提供新建会员、充值、消费和查询余额等功能。
(4)main函数定义一个memberCar类数组或链表,保存会员卡,模拟一个快捷店的会员卡管理功能,主要包括:
① 新建会员;
② 已有会员充值;
③ 已有会员消费(凭密码,不能透支);
④ 输出快捷店当前会员数,营业额(收、支情况)。
#include<iostream>
#include<cstring>
using namespace std;
class RMB
{
int yuan, jiao,
fen;
public:
RMB(int y = 0, int j = 0, int f = 0)
{
yuan = y;
jiao = j;
fen = f;
}
RMB(double x)
{
int n = int((x + 0.005) * 100);
yuan = n / 100;
jiao = (n - yuan * 100) / 10;
fen = n % 10;
}
operator double()
{
return (yuan + jiao * 0.1 + fen * 0.01);
}
~RMB() {}
friend ostream & operator<<(ostream&output, const RMB&m)
{
output << m.yuan << "元" << m.jiao << "角" << m.fen << "分" << endl;
return output;
}
friend istream & operator>>(istream&input, RMB&m)
{
cout << "元:";
input >> m.yuan;
cout << "角:";
input >> m.jiao;
cout << "分:";
input >> m.fen;
return input;
}
};
class member
{
public:
static int number;
char name[20],
code[10], phoneNumber[12];
static int bianhao() { number++; return number; }
member(char*a,char*c,char*p)
{
strcpy_s(name, a);
strcpy_s(code, c);
strcpy_s(phoneNumber, p);
}
~member() {}
friend istream&operator>>(istream&input, member&A)
{
cout << "please input name: " << endl;
input >> A.name;
cout << "please input code: " << endl;
input >> A.code;
cout << "please input phone number : " << endl;
input >> A.phoneNumber;
return input;
}
friend ostream&operator<<(ostream&output, member&A)
{
output << "the information of member:
" << endl;
output << "number" << '\t' << "name" << '\t' << "phone" << endl;
output << A.bianhao() << '\t' << A.name << '\t' << A.phoneNumber << endl;
return output;
}
};
int member::number = 0;
class memberCar :public RMB, public member
{
public:
RMB income, outcome, balance;
memberCar*next;
memberCar(char*a, char*c, char*p):member(a,c,p)
{
balance = 0;
income = 0;
outcome = 0;
}
~memberCar() {}
friend ostream&operator<<(ostream&output, const memberCar&A)
{
output << "the information of member:
" << endl;
output << "number" << '\t' << "name" << '\t' << "phone" << '\t' << '\t' << "balance" << endl;
output << A.bianhao() << '\t' << A.name << '\t' << A.phoneNumber << '\t' << A.balance << endl;
return output;
}
void recharge() //充值函数
{
cout << "How much do you want to recharge?" << '\n' << "please input the money : " << endl;
cin >> income;
balance =balance + income;
cout << "your balance :
" << balance << endl;
}
void cost()
{
char y[10];
cout << "please input your code : " << endl;
cin >> y;
if (strncmp(code, y, 10)==0)
{
cout << "please input the money you cost : " << endl;
cin >> outcome;
if (outcome > balance)
{
cout << "your balance is not enough ! " << endl;
}
else
{
balance = balance - outcome;
cout << "your balance :
"<< balance;
}
}
else
{
cout << "your code is wrong ! " << endl;
}
}
void query(){ cout << "your balance :
" << balance; }
};
void AddFront(memberCar*&h, memberCar*&t) //前插,建立链表。
{
t->next = h;
h = t;
}
void FindList(memberCar*head, int n = 2)
{
char s[20];
cout << "please input your name : " << endl;
cin >> s;
while (head)
{
if (strncmp(head->name, s, 20) == 0) //字符数组之间的比较大小需要使用字符串比较函数。这个是在遍历链表时,通过名字寻找会员卡,然后再进行充值或消费操作。
{
switch (n)
{
case 2:
(*head).recharge();
break;
case 3:
(*head).cost();
break;
}
}
head = head->next;
}
}
void ShowList(memberCar*head) //通过遍历链表来统计会员数、收入、支出和营业额。
{
int count = 0;
RMB I=0, O=0;
while (head)
{
count++;
I=I+head->income;
O = O + head->outcome;
head = head->next;
}
cout << "the number of member : " << count << endl;
cout << "the income of the store : " << I << endl;
cout << "the outcome of the store : " << O << endl;
cout << "turn-over of the store : " << (I - O) << endl;
}
int main()
{
int choice;
memberCar*head = NULL, *p;
do
{
cout << "please choice:\n";
cout << "1 : new member, 2 : recharge, 3 : purchase , 4 :
output the number of member and turn-over,
other number is over! " << endl;
cin >> choice;
switch (choice)
{
case 1:
{
cout << "input information of new member : " << endl;
char a[20],c[10],h[12];
cout << "please input name: " << endl;
cin>>a;
cout << "please input code: " << endl;
cin>>c;
cout << "please input phone number : " << endl;
cin>>h;
p = new memberCar(a, c, h);
AddFront(head, p);
cout << *p << endl;
break;
}
case 2:
{
FindList(head, 2);
break;
}
case 3:
{
FindList(head, 3);
break;
}
case 4:
{
ShowList(head);
break;
}
}
} while (choice);
system("pause");
}
实验结果分析:
(一) 关于字符数组、字符指针,字符串的比较:如果单单比较字符数组和字符指针,得不到想要的结果,因为它实际上比较的是两个地址而不是它们的内容。所以就需要用到字符串的比较函数。 如果是两个字符数组的比较,如果不用字符串的比较函数,就需要用到for循环对数组的元素一个一个进行比较。
(二) 关于指针初始化的问题,建立指后必须要对它进行初始化。 对指针进行初始化或赋值的实质是将一个地址或同类型(或相兼容的类型)的指针赋给它,而不管这个地址是怎么取得的。要注意的是:对于一个不确定要指向何种类型的指针,在定义它之后最好把它初始化为NULL,并在解引用这个指针时对它进行检验,防止解引用空指针。
(三) 每当新建一个会员,都要将它插入链表中。建立一个动态链表,使用前插来建立链表。对于第四个功能查询会员数和营业额,还有调用充值和消费函数,就可以在遍历链表时进行操作。
实验反思:
对于member的构造函数最开始的时候没有写好,直接对name、phone、和code new了空间,之后尽管在member和membercar的析构函数中用了delete,还是会出现中断的问题,这里我还没完全弄懂。
一开始member的构造函数为:
member(int n=0)
{
number=n;
code=new char[10];
phone=new char[12];
name=new char[20];
}
这样写的时候就很难对membercar的构造函数进行初始化,并且还要自定义复制构造函数和析构函数。非常的麻烦。
再者就是关于建立链表的方面,还了解的不够,没能够逐条去读懂语句的意思。应该再多多练习。