包裹系统编写以及过程中发现的错误
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了包裹系统编写以及过程中发现的错误相关的知识,希望对你有一定的参考价值。
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 typedef enum iStatus { Sendtothewarehouse, Hasstarted, Ontheway, Arriveatthewarehouse, Hasbeendistributed, Hasbeenreceived } Status; 6 typedef enum iworkerStatus { Working, Vacation }workerStatus; 7 class Person 8 { 9 private: 10 string name; 11 string PhoneNUM; 12 string address; 13 public: 14 Person(){} 15 Person(string name1, string PhoneNUM1, string address1) :name(name1), PhoneNUM(PhoneNUM1), address(address1) {}; 16 Person(const Person &aq) { 17 name = aq.name; 18 PhoneNUM = aq.PhoneNUM; 19 address = aq.address; 20 } 21 string getname() { 22 return name; 23 } 24 void setP(string name2, string PhoneNUM2, string address2) { 25 name = name2; 26 PhoneNUM = PhoneNUM2; 27 address = address2; 28 29 } 30 void dispaly() { 31 cout << " 姓名:" << name << endl; 32 cout << " 电话:" << PhoneNUM << endl; 33 cout << " 地址:" << address << endl; 34 } 35 }; 36 class Package { 37 public: 38 Package() {}; 39 friend class Sender; 40 Package(const Package& it1) { 41 recipient=it1.recipient; 42 sender=it1.sender; 43 ID = it1.ID; 44 weight = it1.weight; 45 cost = it1.cost; 46 status = it1.status; 47 48 } 49 Package(Person recipient2, Person sender2, string ID, long weight, 50 double cost, Status status) :recipient(recipient2), sender(sender2), ID(ID), weight(weight), cost(cost), status(status) {}; 51 void SetPackage(Person recipient3, Person sender3, string ID3, long weight3, 52 double cost3, Status status3) 53 { 54 recipient = recipient3;sender = sender3;ID = ID3;weight = weight3;cost = cost3;status = status3; 55 }; 56 Person getre() { 57 return recipient; 58 } 59 Person getse() { 60 return sender; 61 } 62 string getID() { 63 return ID; 64 }; 65 Status getStatus() { 66 return status; 67 }; 68 void dispaly() { 69 cout << "*****************包裹信息*****************" << endl; 70 cout << "收件人信息:" << endl; 71 recipient.dispaly(); 72 cout << "发件人信息:" << endl; 73 sender.dispaly(); 74 cout << "包裹编号:" << ID << endl; 75 cout << "包裹重量:" << weight << endl; 76 cout << "包裹费用:" << cost << endl; 77 cout << "包裹状态:" << status << endl; 78 cout << "*****************************************" << endl; 79 } 80 81 protected: 82 Person recipient; 83 Person sender; 84 string ID; 85 long weight; 86 double cost; 87 Status status; 88 }; 89 class Link { 90 public: 91 Package pac; 92 Link *next; 93 Link(Package elemval, Link* nextval = NULL) { pac = elemval;next = nextval; } 94 Link(Link* nextval = NULL) { next = nextval; } 95 }; 96 class package_list { 97 private: 98 Link *head; 99 Link *tail; 100 Link *curr; 101 int cnt; 102 void create() { 103 curr = head = tail = new Link; 104 cnt = 0; 105 }; 106 void removeall() { 107 while (head != NULL) { 108 curr = head; 109 head = head->next; 110 delete curr; 111 } 112 } 113 public: 114 package_list() { 115 create(); 116 }; 117 void clear() { removeall(); create(); } 118 void delete_pac() { 119 curr = head; 120 while(tail!=curr){ 121 if ((curr->pac).getStatus() == Hasbeenreceived) { 122 if (tail == curr->next) { tail = curr; } 123 Link* temp = curr->next; 124 curr->next = curr->next->next; 125 delete temp; 126 cnt--; 127 curr = curr->next; 128 } 129 } 130 }; 131 132 void change(string ID) { 133 curr = head; 134 while (curr != tail&&curr->next->pac.getID() !=ID) { 135 curr = curr->next; 136 137 } 138 if (curr == tail) { cout << "包裹中没有此ID"<<endl; } 139 else { 140 cout << "请输入此包裹修改后的收件人信息" << endl;; 141 string nam, phoneNU, addre,ID3; 142 143 cin >> nam >> phoneNU >> addre; 144 Person recipient3(nam, phoneNU, addre); 145 cout << "请输入此包裹修改后的发件人信息"<<endl;; 146 cin >> nam >> phoneNU >> addre; 147 Person sender3(nam, phoneNU, addre); 148 cout << "请输入此包裹修改后的ID,重量,价值,状态" << endl;; 149 long weight3; 150 double cost3; 151 Status status3; 152 cin >> weight3 >> cost3 >> (int&)status3; 153 154 curr->next->pac.SetPackage(recipient3, sender3, ID3, weight3, 155 cost3, status3); 156 } 157 158 } 159 160 void append(Package it) { 161 tail = tail->next = new Link(it, NULL); 162 cnt++; 163 } 164 165 166 Package* search_re(string name) { 167 curr = head; 168 for (int i = 0;curr->next != NULL;i++) { 169 if ((curr->pac).getre().getname() == name) return &curr->next->pac; 170 curr = curr->next; 171 } 172 cout<<"未找到"; 173 return NULL; 174 } 175 Package* search_se(string name) { 176 curr = head; 177 for (int i = 0;curr->next != NULL;i++) { 178 if ((curr->pac).getse().getname() == name) return &curr->next->pac; 179 curr = curr->next; 180 } 181 cout<<"未找到"; 182 return NULL; 183 } 184 Package* search_ID(string ID) { 185 curr = head; 186 for (int i = 0;curr->next != NULL;i++) { 187 if ((curr->next->pac).getID() == ID) return &curr->next->pac; 188 else curr = curr->next; 189 } 190 cout<<"未找到"; 191 return NULL; 192 } 193 void dispaly() { 194 curr = head; 195 while (curr->next != NULL) { 196 (curr->next->pac).dispaly(); 197 curr = curr->next; 198 } 199 } 200 }; 201 class Sender :public Person { 202 public: 203 Sender() {} 204 Sender(string name, string PhoneNUM, string address, workerStatus ws) :Person(name, PhoneNUM, address), ws(ws) {} 205 void set(string name3, string PhoneNUM3, string address3, workerStatus ws3) { 206 ws = ws3; 207 setP(name3, PhoneNUM3,address3); 208 } 209 void dispalySender() { 210 cout<<"**************快递员信息*****************"<<endl; 211 cout << "快递员信息:" << endl; 212 Person::dispaly(); 213 cout << "当前工作状态:" << ws << endl; 214 cout<<"*****************************************"<<endl; 215 } 216 void enPackage(Package pack, package_list* list) 217 { 218 list->append(pack); 219 } 220 void deletePa(package_list* list) { 221 return list->delete_pac(); 222 } 223 Package* findPac_se(string name, package_list* list) { 224 return list->search_se(name); 225 } 226 Package* findPac_re(string name, package_list* list) { 227 return list->search_re(name); 228 } 229 Package* findPac_ID(string IDnum, package_list* list) { 230 return list->search_ID(IDnum); 231 } 232 void showPac(package_list* list) { list->dispaly(); } 233 void changePac(string ID5, package_list* list) { list->change(ID5); } 234 235 private: 236 workerStatus ws; 237 }; 238 class mange { 239 public: 240 mange (){} 241 void showSender(Sender* sen) { sen->dispalySender(); } 242 void mashowPac(package_list* list) { list->dispaly(); } 243 void machangePac(string ID6, package_list* list) { list->change(ID6); }//除此之外可以添加修改快递员信息的接口 244 }; 245 246 void main() 247 { 248 string namemain, phonemain, addressmain; 249 int n,m; 250 workerStatus wstatus; 251 package_list pl; 252 Sender S1; 253 cout << "请输入快递员姓名,电话,地址,工作状态(输入整数0为工作,1为放假,)" << endl; 254 cin >> namemain >> phonemain >> addressmain >> (int&)wstatus; 255 S1.set(namemain, phonemain, addressmain, wstatus); 256 cout << "请问您有几个包裹信息需要填写" << endl; 257 cin >> m; 258 Package *pp = new Package[m];//创建包裹的对象数组 259 for (int j = 0;j < m;j++) 260 { 261 cout << "请输入收件人姓名,电话,地址"<<endl; 262 long wei; 263 double cost8; 264 Status ss; 265 string namemain1, phonemain1, addressmain1; 266 cin >> namemain1 >> phonemain1 >> addressmain1; 267 Person recone(namemain1, phonemain1, addressmain1); 268 cout << "请输入发件人姓名,电话,地址"<<endl; 269 string namemain2, phonemain2, addressmain2,ID0; 270 cin >> namemain2 >> phonemain2 >> addressmain2; 271 Person secone(namemain2, phonemain2, addressmain2); 272 cout << "请输入包裹ID,重量,费用,状态(0为Sendtothewarehouse,1为 Hasstarted,2为 Ontheway,3为 Arriveatthewarehouse,4为 Hasbeendistributed, 5为Hasbeenreceived )" << endl; 273 cin >> ID0 >> wei >> cost8 >> (int&)ss;//如何接受enum类型: 274 pp[j].SetPackage(recone, secone, ID0, wei, cost8, ss); 275 pl.append(pp[j]); 276 } 277 mange master; 278 master.showSender(&S1);//管理员显示快递员信息 279 cout<<endl; 280 master.mashowPac(&pl);//管理员显示包裹信息 281 cout<<endl; 282 string ID;//以下测试查找包裹 283 cin>>ID; 284 Package* P1 =S1.findPac_ID(ID,&pl); 285 P1->dispaly(); 286 string rename; 287 string sename; 288 cin>>rename; 289 Package *P2=S1.findPac_re(rename,&pl); 290 P2->dispaly(); 291 cin>>sename; 292 Package *P3=S1.findPac_se(sename,&pl); 293 P3->dispaly(); 294 delete [] pp; 295 system("pause"); 296 }
该程序是我们C++的一个实验,为期一周,所以简单的做了一下,其中有很多没有完善的地方。
main函数为测试函数,测试结果为:
1.程序中对enum的输出只是简单的使用数字代替,因为enum类型是int整型,如果想让它输出字符串类型可以使用如下方法:
1 char * StringDirectionT(directionT dir) 2 { 3 switch(dir) 4 { 5 case North : return "North"; 6 case East : return "East"; 7 case South : return "South"; 8 case West : return "West"; 9 default : printf("Illegal direction value!\\n; 10 } 11 }
printf("The direction is %s \\n",StringDirectionT(dir));
上面程序中可以在display中针对输入的整型数值采用上述函数(该函数声明为全局函数)转换为想要输出的中文字符串。enum类型最好使用英文字符,中文可能会报错。
2.name(name)是初始化特有的,赋值必须使用等号。
3.转自http://www.cnblogs.com/xiaorenwu702/p/5794330.html
new和不new的区别
1 #include <iostream> 2 using namespace std; 3 4 5 class A 6 { 7 private: 8 int n; 9 public: 10 A(int m):n(m) 11 { 12 } 13 ~A(){} 14 }; 15 16 int main() 17 { 18 A a(1); //栈中分配 19 A b = A(1); //栈中分配 20 A* c = new A(1); //堆中分配 21 delete c; 22 return 0; 23 }
第一种和第二种没什么区别,一个隐式调用,一个显式调用,两者都是在进程虚拟地址空间中的栈中分配内存,而第三种使用了new,在堆中分配了内存,而栈中内存的分配和释放是由系统管理,而堆中内存的分配和释放必须由程序员手动释放,所以这就产生一个问题是把对象放在栈中还是放在堆中的问题,这个问题又和堆和栈本身的区别有关:
这里面有几个问题:
1.堆和栈最大可分配的内存的大小
2.堆和栈的内存管理方式
3.堆和栈的分配效率
首先针对第一个问题,一般来说对于一个进程栈的大小远远小于堆的大小,在linux中,你可以使用ulimit -s (单位kb)来查看一个进程栈的最大可分配大小,一般来说不超过8M,有的甚至不超过2M,不过这个可以设置,而对于堆你会发现,针对一个进程堆的最大可分配的大小在G的数量级上,不同系统可能不一样,比如32位系统最大不超过2G,而64为系统最大不超过4G,所以当你需要一个分配的大小的内存时,请用new,即用堆。
其次针对第二个问题,栈是系统数据结构,对于进程/线程是唯一的,它的分配与释放由操作系统来维护,不需要开发者来管理。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时,这些存储单元会被自动释放。栈内存分配运算内置于处理器的指令集中,效率很高,不同的操作系统对栈都有一定的限制。 堆上的内存分配,亦称动态内存分配。程序在运行的期间用malloc申请的内存,这部分内存由程序员自己负责管理,其生存期由开发者决定:在何时分配,分配多少,并在何时用free来释放该内存。这是唯一可以由开发者参与管理的内存。使用的好坏直接决定系统的性能和稳定。
由上可知,但我们需要的内存很少,你又能确定你到底需要多少内存时,请用栈。而当你需要在运行时才知道你到底需要多少内存时,请用堆。
最后针对第三个问题,栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率 比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在 堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
由上可知,能用栈则用栈。
1 #include <stdio.h> 2 #include <stdlib.h> 3 void main() 4 { 5 int n,*p,i,j,m; 6 printf("本程序可对任意个整数排序;\\n"); 7 printf("请输入整数的总个数: "); 8 scanf("%d",&n); 9 p=(int *)calloc(n,sizeof(int)); //运行时决定内存分配大小 10 if(p==0) { 11 printf("分配失败!\\n"); 12 exit(1); 13 }
4.关于对象指针和对象引用
首先必须明白
1 int i =10; 2 int &j = i; //&符号紧随类型名出现,它是声明的一部分,j是一个引用。 3 int *p; //*符号紧随类型名出现,它是声明的一部分,p是一个指针。 4 p = &i; //&符号出现在表达式之中,是一个取地址符号。 5 *p = i; //*符号出现在表达式之中,是一个解引用符 6 int &j2 = *p; //&是声明的一部分,*是解引用符。
在上面程序中
1 Package* search_ID(string ID) { 2 curr = head; 3 for (int i = 0;curr->next != NULL;i++) { 4 if ((curr->next->pac).getID() == ID) return &curr->next->pac; 5 else curr = curr->next; 6 } 7 cout<<"未找到"; 8 return NULL; 9 }
一开始我使用package作为返回类型,报错:不是所有控件路径都有返回值;因为如果没找到的话,就没办法返回一个正确的类对象,所以我改成了指针,这样可以返回NULL。
程序中Package类中为了得到收件人发件人信息直接返回了类对象,这是可行的。
1 Person getre() { 2 return recipient; 3 }