1.#include <string.h>2.#include <stdio.h>3.4.struct parent5.{6.static char* expression;7.static int index;8.static int end_state;9.static int doom_state;10.11. parent(char* expr);12.virtual parent* transition() {}13.};14.15.parent::parent(char* expr)16.{17. expression = new char[strlen(expr)];18. strcpy(expression,expr);19. end_state = 0;20. doom_state = 0;21. index = 0;22.}23.24.struct state1:public parent25.{26. parent *ptr2,*ptr3,*ptr4,*ptr5;27. state1():parent(expression) {}28. parent* transition();29.};30.31.struct state2:public parent32.{33. parent *ptr2;34. state2():parent(expression) {}35. parent* transition();36.};37.38.struct state3:public parent39.{40. parent *ptr3,*ptr4;41. state3():parent(expression) {}42. parent* transition();43.};44.45.struct state4:public parent46.{47. parent *ptr4;48. state4():parent(expression) {}49. parent* transition();50.};51.52.struct state5:public parent53.{54. parent *ptr2,*ptr4,*ptr5;55. state5():parent(expression) {}56. parent* transition();57.};58.59.parent* state1::transition()60.{61.switch(expression[index++])62. {63.case'A':64.return ptr2;65.case'B':66.return ptr3;67.case'C':68.return ptr4;69.case'D':70.return ptr5;71.case'/0':72. doom_state = 1;73.default:74. doom_state = 1;75. }76.}77.78.parent* state2::transition()79.{80.switch(expression[index++])81. {82.case'E':83.return ptr2;84.case'I':85. end_state = 1;86.break;87.case'/0':88. doom_state = 1;89.default:90. doom_state = 1;91. }92.}93.94.parent* state3::transition()95.{96.switch(expression[index++])97. {98.case'F':99.return ptr3;100.case'M':101.return ptr4;102.case'J':103. end_state = 1; 104.break;105.case'/0':106. doom_state = 1; 107.default:108. doom_state = 1; 109. }110.}111.112.parent* state4::transition() 113.{114.switch(expression[index++]) 115. {116.case'G':117.return ptr4;118.case'K':119. end_state = 1; 120.break;121.case'/0':122. doom_state = 1; 123.default:124. doom_state = 1; 125. }126.}127.128.parent* state5::transition() 129.{130.switch(expression[index++]) 131. {132.case'O':133.return ptr2;134.case'H':135.return ptr5;136.case'L':137. end_state = 1; 138.break;139.case'N':140.return ptr4;141.case'/0':142. doom_state = 1;143.default:144. doom_state = 1;145. }146.}147.148.char* parent::expression = NULL;149.int parent::doom_state = 0;150.int parent::end_state = 0;151.int parent::index = 0;152.153.state1 s1;154.state2 s2;155.state3 s3;156.state4 s4;157.state5 s5;158.159.void build_state_machine()160.{161. s1.ptr2 = &s2;162. s1.ptr3 = &s3;163. s1.ptr4 = &s4;164. s1.ptr5 = &s5;165. s2.ptr2 = &s2;166. s3.ptr3 = &s3;167. s3.ptr4 = &s4;168. s4.ptr4 = &s4;169. s5.ptr2 = &s2;170. s5.ptr4 = &s4;171. s5.ptr5 = &s5;172.}173.174.int main()175.{176. build_state_machine();177.char input_string[80];178. printf("Enter input expression: ");179. scanf("%s",input_string);180. parent state_machine(input_string);181. parent *ptr;182. ptr = s1.transition();183.while(ptr->end_state !=1 && ptr->doom_state != 1) 184. {185. ptr = ptr->transition();186. }187.if(ptr->end_state == 1)188. printf("/nValid input expression");189.else190. printf("/nInvalid input expression");191.192.return 0;193.}1. expression = new char[strlen(expr)];这句中字符串后应该有空格存在,应加1.2. 依照执行顺序,最开始执行的是全局对象s1到s5的构造函数。
s1的构造函数执行后expression将指向动态开辟的内存的地址,s2执行时,expression又指向另一新开辟内存,原理开辟的内存成为垃圾内存,形成内存泄露。
3. s1构造完后,本身的地址值是不变的,因而可用&s1代替ptr1等等。
4. 程序中对state_machine的使用仅仅是为了执行它的构造函数,将FSM重置为初始状态。
而将FSM重置为初始状态并不是初始化。
FSM是一组静态变量。
我们应该使用静态成员函数将FSM重置为起始状态。
原则:不要使用构造函数来初始化静态数据成员。
基于上面的分析,做如下改动:1. 用静态成员函数来reset()代替parent的构造函数。
2. 改正缺1错误。
3. 从main()中去掉state_machine,并直接调用parent::reset()。
4. 去掉每个statej的构造函数。
5. 去掉statej::ptri成员,并用&si代替。
6. 去掉build_state_machine()。
[cpp]view plaincopy1.#include <string.h>2.#include <stdio.h>3.4.struct parent5.{6.static char* expression;7.static int index;8.static int end_state;9.static int doom_state;10.11.static void reset(char* expr);12.virtual parent* transition() {}13.};14.15.void parent::reset(char* expr)16.{17. expression = new char[strlen(expr) + 1];18. strcpy(expression,expr);19. end_state = 0;20. doom_state = 0;21. index = 0;22.}23.24.struct state1:public parent25.{26. parent* transition();27.};28.29.struct state2:public parent30.{31. parent* transition();32.};33.34.struct state3:public parent35.{36. parent* transition();37.};38.39.struct state4:public parent40.{41. parent* transition();42.};43.44.struct state5:public parent45.{46. parent* transition();47.};48.49.char* parent::expression = NULL;50.int parent::doom_state = 0;51.int parent::end_state = 0;52.int parent::index = 0;53.54.state1 s1;55.state2 s2;56.state3 s3;57.state4 s4;58.state5 s5;59.60.parent* state1::transition()61.{62.switch(expression[index++])63. {64.case'A':65.return &s2;66.case'B':67.return &s3;68.case'C':69.return &s4;70.case'D':71.return &s5;72.case'/0':73. doom_state = 1;74.default:75. doom_state = 1;76. }77.}78.79.parent* state2::transition()80.{81.switch(expression[index++])82. {83.case'E':84.return &s2;85.case'I':86. end_state = 1;87.break;88.case'/0':89. doom_state = 1;90.default:91. doom_state = 1;92. }93.}94.95.parent* state3::transition()96.{97.switch(expression[index++])98. {99.case'F':100.return &s3;101.case'M':102.return &s4;103.case'J':104. end_state = 1; 105.break;106.case'/0':107. doom_state = 1; 108.default:109. doom_state = 1; 110. }111.}112.113.parent* state4::transition() 114.{115.switch(expression[index++]) 116. {117.case'G':118.return &s4;119.case'K':120. end_state = 1; 121.break;122.case'/0':123. doom_state = 1; 124.default:125. doom_state = 1; 126. }127.}128.129.parent* state5::transition()130.{131.switch(expression[index++])132. {133.case'O':134.return &s2;135.case'H':136.return &s5;137.case'L':138. end_state = 1;139.break;140.case'N':141.return &s4;142.case'/0':143. doom_state = 1;144.default:145. doom_state = 1;146. }147.}148.149.int main()150.{151.char input_string[80];152. printf("Enter input expression: ");153. scanf("%s",input_string);154. parent::reset(input_string);155. parent *ptr;156. ptr = s1.transition();157.while(ptr->end_state !=1 && ptr->doom_state != 1) 158. {159. ptr = ptr->transition();160. }161.if(ptr->end_state == 1)162. printf("/nValid input expression");163.else164. printf("/nInvalid input expression");165.166.return 0;167.}程序分析和改进:∙main()的变量Ptr中记录了FSM的当前状态,而FSM管理着输入的字符串,这些都是对方的职责。