picture.h
#ifndef PICTURE_H
#define PICTURE_H
#include<iostream>
using namespace std;
class Picture
{
public:
Picture();
Picture(const char* const*, int);
Picture(const Picture&);
Picture& operator=(const Picture&);
~Picture();
private:
int m_height;
int m_width;
char* m_data;
//获取固定位置上的字符,可以作为左值进行读写
char& position(int row, int col)
{
return m_data[row * m_width + col];
}
//获取固定位置上的字符的副本
char position(int row, int col) const
{
return m_data[row * m_width + col];
}
//初始化
void init(int height, int width);
//静态函数,比较两个数的大小,用于获取字符串数组中最长的长度
static int max(int m, int n);
//用于拷贝picture到固定起始位置开始的区域
void copyBlock(int m, int n, const Picture&);
//清理无用区域
void clear(int x, int y, int height, int width);
friend ostream& operator<<(ostream&, const Picture&);
friend Picture frame(const Picture&);
friend Picture operator&(const Picture&, const Picture&);
friend Picture operator|(const Picture&, const Picture&);
};
#endif // PICTURE_H
picture.cpp
#include "picture.h"
#include <string.h>
Picture::Picture()
:m_height(0), m_width(0), m_data(0)
{
}
Picture::Picture(const char* const* array, int n)
{
int w = 0;
for (int i = 0; i < n; i++)
{
w = Picture::max(w, strlen(array[i]));
}
init(n, w);
for (int i = 0; i<n; i++)
{
const char* src = array[i];
int len = strlen(src);
int j = 0;
while (j < len)
{
position(i, j) = src[j];
++j;
}
//给每一行中余下的位置要添上空格
while (j< m_width)
{
position(i, j) = ' ';
++j;
}
}
}
Picture::Picture(const Picture& p)
:m_height(p.m_height), m_width(p.m_width),
m_data(new char[p.m_height * p.m_width])
{
copyBlock(0 ,0 ,p);
}
Picture& Picture::operator=(const Picture& p)
{
if (this != &p)
{
delete[] m_data;
init(p.m_height, p.m_width);
copyBlock(0, 0, p);
}
return *this;
}
Picture::~Picture()
{
}
void Picture::init(int height, int width)
{
m_height = height;
m_width = width;
m_data = new char[height * width];
}
int Picture::max(int m, int n)
{
return m>n ? m:n;
}
void Picture::copyBlock(int m, int n, const Picture& p)
{
for (int i = 0; i < p.m_height; i++)
{
for (int j = 0; j < p.m_width; j++)
{
position(i + m, j + n) = p.position(i, j);
}
}
}
void Picture::clear(int x, int y, int height, int width)
{
for (int i = x; i < height; ++i)
{
for (int j = y; j < width; ++j)
{
position(i, j) = ' ';
}
}
}
ostream& operator<<(ostream& o, const Picture& p)
{
for (int i = 0; i < p.m_height; i++)
{
for (int j = 0; j < p.m_width; j++)
{
o << p.position(i, j);
}
o << endl;
}
return o;
}
Picture frame(const Picture& p)
{
Picture r;
r.init(p.m_height + 2, p.m_width + 2);
//左右两边边框“|”
for (int i = 1; i< r.m_height - 1; ++i)
{
r.position(i, 0) = '|';
r.position(i, r.m_width - 1) = '|';
}
//上下边框“-”
for (int j = 1; j < r.m_width - 1; ++j)
{
r.position(0, j) = '-';
r.position(r.m_height - 1, j) = '-';
}
//四个角“+”
r.position(0, 0) = '+';
r.position(0, r.m_width - 1) = '+';
r.position(r.m_height -1, 0) = '+';
r.position(r.m_height -1, r.m_width - 1) = '+';
r.copyBlock(1, 1, p);
return r;
}
Picture operator&(const Picture& up, const Picture& down)
{
Picture r;
r.init(up.m_height + down.m_height,
Picture::max(up.m_width, down.m_width));
//将组合后的无用单元设置成空格
r.clear(0, up.m_width, up.m_height, r.m_width);
r.clear(up.m_height, down.m_width, r.m_height, r.m_width);
r.copyBlock(0, 0, up);
r.copyBlock(up.m_height, 0, down);
return r;
}
Picture operator|(const Picture& left, const Picture& right)
{
Picture r;
r.init(Picture::max(left.m_height, right.m_height),
left.m_width + right.m_width);
r.clear(left.m_height, 0, r.m_height, left.m_width);
r.clear(right.m_height, left.m_width, r.m_height, r.m_width);
r.copyBlock(0, 0, left);
r.copyBlock(0, left.m_width, right);
return r;
}
#include <iostream>
#include "picture.h"
using namespace std;
char* init[] = {"Pairs", "in the", "Spring"};
int main()
{
Picture p(init, 3);
cout << p << endl;
Picture q = p;
cout << q << endl;
Picture fq = frame(q);
cout << fq << endl;
Picture fqq = (fq & q);
cout << fqq << endl;
Picture p_fqq = p | (frame(q) & q);
cout << p_fqq << endl;
Picture fpfqq = frame(p_fqq);
cout << fpfqq << endl;
return 0;
}
运行结果:
Pairs
in the
Spring
Pairs
in the
Spring
+------+
|Pairs |
|in the|
|Spring|
+------+
+------+
|Pairs |
|in the|
|Spring|
+------+
Pairs
in the
Spring
Pairs +------+
in the|Pairs |
Spring|in the|
|Spring|
+------+
Pairs
in the
Spring
+--------------+
|Pairs +------+|
|in the|Pairs ||
|Spring|in the||
| |Spring||
| +------+|
| Pairs |
| in the |
| Spring |
+--------------+
缺陷:
首先,复制图像就要复制字符,而且再把一幅小图像并到大图像的过程中,也要复制其内部字符。
其次,可能需要花费不少内存来存储空格,如果图像其中某一行明显比其他各行长得多,那么这一开销就不容忽视了。
最后,该方案将所有图像内部结构信息都丢掉了。
下一章,将重新设计。