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
#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 | +--------------+
首先,复制图像就要复制字符,而且再把一幅小图像并到大图像的过程中,也要复制其内部字符。
其次,可能需要花费不少内存来存储空格,如果图像其中某一行明显比其他各行长得多,那么这一开销就不容忽视了。
最后,该方案将所有图像内部结构信息都丢掉了。
下一章,将重新设计。