The author constructed the Picture class and summarized the details of the requirement. For details, refer to the recruitment and splitting actions. In the "Interface Design" section, he treats himself as a customer, ask yourself ("What operations do I want and how do I express these operations? "), Gradually analyze complex requirements and then abstract the interfaces, which are based on the author's experience: to determine the specific operation form, there is a good way to try to use these operations, it is much easier to deduce the definition form of an operation from the example in use than to create it from the beginning.
1. The initial requirement is to print the following text:
Paris
In
Spring
2. For the constructed Picture class, you only need one constructor and one output. If the following text is printed:
+ ------- +
| Paris |
| In the |
| Spring |
+ ------- +
3. If the C-type process code is used, some changes to the printed content can be completed. The author adds a frame (Picture &) for the Picture class. If the printed content changes, I think the C-type code author will be scratching his head:
Paris + ------- +
In the | Paris |
Spring | in the |
| Spring |
+ ------- +
4. The Picture class has the Picture operator | (const Picture &, const Picture &) interface. Use the character '|' to merge two Picture objects horizontally, use the Picture operator & (const Picture &, const Picture &) interface and the character '&' for vertical merge. When we need to print the following text:
+ -------------- +
| + ------ + |
| Paris |
| In the |
| Spring |
| + ------ + |
| Paris + ------ + |
| In the | Paris |
| Spring | in the |
| Spring |
| + ------ + |
+ -------------- +
We only need a cout statement <frame (p) & (p | frame (p) <endl to complete.
The following is the source code of the Picture class (the original book code has some errors and has been modified and tested ):
1 # include <iostream>
2
3
4 using namespace std;
5
6 class Picture
7 {
8 friend Picture frame (const Picture &); // framed
9 friend Picture operator & (const Picture &, const Picture &); // vertically merged
10 friend Picture operator | (const Picture &, const Picture &); // merge horizontally
11 friend ostream & operator <(ostream & o, const Picture & p );
12 private:
13 int height, width;
14 char * data;
15 char & position (int row, int col ){
16 return data [row * width + col];
17 };
18 char position (int row, int col) const {
19 return data [row * width + col];
20 };
21 void copyblock (int, int, const Picture &);
22 public:
23 Picture (): height (0), width (0), data (0 ){};
24 Picture (const char * const *, int );
25 Picture (const Picture &);
26 ~ Picture ();
27 Picture & operator = (const Picture &);
28 static int max (int m, int n)
29 {
30 return m> n? M: n;
31 };
32 void init (int h, int w );
33 void clear (int, int );
34 };
35
36 ostream &
37 operator <(ostream & o, const Picture & p)
38 {
39 for (int I = 0; I <p. height; ++ I)
40 {
41 for (int j = 0; j <p. width; ++ j)
42 o <p. position (I, j );
43 o <endl;
44}
45 return o;
46 };
47
48
49 void Picture: init (int h, int w)
50 {
51 height = h;
52 width = w;
53 data = new char [height * width];
54 };
55
56 Picture: Picture (const char * const * array, int n)
57 {
58 int w = 0;
59 int I;
60 for (I = 0; I <n; I ++)
61 w = Picture: max (w, strlen (array [I]);
62 init (n, w );
63 for (I = 0; I <n; I ++)
64 {
65 const char * src = array [I];
66 int len = strlen (src );
67 int j = 0;
68 while (j <len)
69 {
70 position (I, j) = src [j];
71 ++ j;
72}
73 while (j <width)
74 {
75 position (I, j) = '';
76 + + j;
77}
78}
79}
80
81 Picture: Picture (const Picture & p ):
82 height (p. height), width (p. width ),
83 data (new char [p. height * p. width])
84 {
85 copyblock (0, 0, p );
86}
87
88 Picture ::~ Picture ()
89 {
90 delete [] data;
91}
92
93 Picture & Picture: operator = (const Picture & p)
94 {
95 if (this! = & P)
96 {
97 delete [] data;
98 init (p. height, p. width );
99 copyblock (0, 0, p );
100}
101 return * this;
102}
103
104 void Picture: copyblock (int row, int col, const Picture & p)
105 {
106 for (int I = 0; I <p. height; ++ I)
107 {
108 for (int j = 0; j <p. width; ++ j)
109 position (I + row, j + col) = p. position (I, j );
110}
111}
112
113 void Picture: clear (int h1, int w1, int h2, int w2)
114 {
115 for (int r = h1; r
116 for (int c = w1; c <w2; ++ c)
117 position (r, c) = '';
118}
119
120 Picture frame (const Picture & p)
121 {
122 pictrue r;
123 r. init (p. height + 2, p. width + 2 );
124 for (int I = 1; I <r. height-1; ++ I)
125 {
126 r. position (I, 0) = '| ';
127 r. position (I, r. width-1) = '| ';
128}
129 for (int j = 1; j <r. width-1; ++ j)
130 {
131 r. position (0, j) = '-';
132 r. position (r. height-1, j) = '-';
133}
134 r. position (0, 0) = '+ ';
135 r. position (0, r. width-1) = '+ ';
136 r. position (r. height-1, 0) = '+ ';
137 r. position (r. height-1, r. width-1) = '+ ';
138 r. copyblock (, p );
139 return r;
140}
141
142 Picture operator & (const Picture & p, const Picture & q)
143 {
144 pictrue r;
145 r. init (p. height + q. height, Picture: max (p. width, q. width ));
146 r. clear (0, p. width, p. height, r. width );
147 r. clear (p. height, q. width, r. height, r. width );
148 r. copyblock (, p );
149 r. copyblock (p. height, 0, q );
150 return r;
151}
152
153 Picture operator | (const Picture & p, const Picture & q)
154 {
155 pictrue r;
156 r. init (Picture: max (p. height, q. height), p. width + q. width );
157 r. clear (p. height, 0, r. height, q. width );
158 r. clear (q. height, p. width, r. height, r. width );
159 r. copyblock (, p );
160 r. copyblock (0, p. width, q );
161 return r;
162}
Test code:
1 char * init [] = {"Paris", "in the", "Spring "};
2 Picture p (init, 3 );
3 cout <frame (p) & (p | frame (p) <endl;