1 #include <iostream>
2 using namespace std;
3 class Picture;
4 ostream& operator<<(ostream&,const Picture&);
5 Picture frame(const Picture&);
6 Picture operator&(const Picture&,const Picture&);
7 Picture operator|(const Picture&,const Picture&);
8
9 class Picture
10 {
11 friend ostream& operator<<(ostream&,const Picture&);
12 friend Picture frame(const Picture&);
13 friend Picture operator&(const Picture&,const Picture&);
14 friend Picture operator|(const Picture&,const Picture&);
15 public:
16
17 int height,width;
18
19 Picture();
20 Picture(const string*,int);
21 Picture(const Picture&);
22 ~Picture();
23
24 Picture& operator=(const Picture&);
25
26 char& position(int row,int col){ return data[row * width + col]; }///允许作为左值,可写
27 char position(int row,int col) const{ return data[row * width + col]; }////返回当前位置的值
28
29 private:
30 char* data;
31 void copyblock(int ,int ,const Picture&);
32 void clear(int,int,int,int);
33 void init(int ,int);
34 static int max(int ,int);
35 };
36 //当构建的图为空时,高度宽度为零,数据指针为空//
37 Picture::Picture() : height(0),width(0),data(0){}
38
39 //用于比较出字符数组中最常的长度,用以分配内存//
40 int Picture::max(int m, int n)
41 {
42 return m>n?m:n;
43 }
44
45 //分配内存并且将指针赋给data同时也保存了长度和宽度//
46 void Picture::init(int h, int w)
47 {
48 height = h;
49 width = w;
50 data = new char[height * width];
51 }
52 //将array字符数组中的字符复制到Picture类对象的data中//
53 Picture::Picture(const string* array, int n)
54 {
55 int w = 0;
56 int i;
57
58 for(i=0; i<n; i++)
59 {
60 w = Picture::max(w,array[i].length());
61 }
62
63 init(n,w);
64
65 for(i = 0; i<n; i++)
66 {
67 const string src = array[i];
68 int len = src.length();
69 int j = 0;
70 while(j<len)
71 {
72 position(i,j) = src[j];
73 ++j;
74 }
75 while(j<width)
76 {
77 position(i,j) = ' ';
78 ++j;
79 }
80 }
81 }
82
83 //将一个picture类的对象复制给另一个picture类的对象//
84 Picture::Picture(const Picture& p):height(p.height),width(p.width),data(new char[p.height*p.width])
85 {
86 copyblock(0,0,p);
87 }
88
89 //析构函数//
90 Picture::~Picture(){delete []data;}
91
92 //将一个图像(picture类)赋给另一个picture对象//
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 //从指定位置开始复制//
105 void Picture::copyblock(int row, int col, const Picture& p)
106 {
107 for(int i=0;i<p.height; i++)
108 for(int j=0; j<p.width; j++)
109 position(i+row,j+col) = p.position(i,j);
110 }
111
112 //输出符重载//
113 ostream& operator<<(ostream& o, const Picture& p)
114 {
115 for(int i=0;i<p.height;i++)
116 {
117 for(int j=0; j<p.width;j++)
118 o<<p.position(i,j);
119 o<<endl;
120 }
121
122 return o;
123 }
124
125 //给图像加上边框,p是源图像//
126 Picture frame(const Picture& p)
127 {
128 Picture r;
129 r.init(p.height+2, p.width+2);
130
131 for(int i=1; i<r.height-1; i++)
132 {
133 r.position(i,0)='|';
134 r.position(i, r.width-1)='|';
135 }
136
137 for(int j=1; j<r.width-1; ++j)
138 {
139 r.position(0,j) = '-';
140 r.position(r.height-1,j) = '-';
141 }
142
143 r.position(0,0) = '+';
144 r.position(0,r.width -1) = '+';
145 r.position(r.height - 1,0) = '+';
146 r.position(r.height - 1,r.width-1) = '+';
147
148 r.copyblock(1,1,p);
149 return r;
150 }
151
152 //清楚多余部分//
153 void Picture::clear(int r1, int c1, int r2, int c2)
154 {
155 for(int r=r1;r<r2;++r)
156 for(int c=c1;c<c2;++c)
157 position(r,c) = ' ';
158 }
159
160 //纵向连接两幅图//
161 Picture operator&(const Picture& p, const Picture& q)
162 {
163 Picture r;
164 r.init(p.height+q.height,Picture::max(p.width,q.width));
165 r.clear(0, p.width,p.height,r.width);
166 r.clear(p.height,q.width,r.height,r.width);
167 r.copyblock(0,0,p);
168 r.copyblock(p.height,0,q);
169 return r;
170 }
171
172 //横向连接两幅图//
173 Picture operator|(const Picture& p,const Picture& q)
174 {
175 Picture r;
176 r.init(Picture::max(p.height, q.height),p.width+q.width);
177 r.clear(p.height,0,r.height,p.width);
178 r.clear(q.height,p.width,r.height,r.width);
179
180 r.copyblock(0,0,p);
181 r.copyblock(0,p.width,q);
182 return r;
183 }
184
185 int main()
186 {
187 string init[]={"bystander","I live in","cnblogs"};
188 Picture p(init,3);
189 cout<<p<<endl;
190
191 Picture q = frame(p);
192 cout<<q<<endl;
193
194 Picture r = p | q;
195 cout<<r<<endl;
196
197 Picture s = q & r;
198 cout<<s<<endl<<frame(s)<<endl;
199
200 Picture e = frame(s) | frame(s);
201 cout<<e<<endl;
202 return 0;
203 }