#ifndef NEWPICTURE_H #define NEWPICTURE_H #include<iostream> using namespace std; class P_Node { friend class Picture; protected: P_Node(); virtual ~P_Node(){}; virtual int width()const=0; virtual int height()const=0; virtual void display(ostream &, int, int)const=0; int max(int x, int y)const { return x > y ? x : y; } void pad(ostream & os, int x, int y)const ; private: int use; }; class Picture { friend class String_Pic; friend class Frame_Pic; friend class Hcat_Pic; friend class Vcat_Pic; public: Picture(); Picture(const char * const *, int); Picture(const Picture &); ~Picture(); Picture & operator =(const Picture &); P_Node * p; Picture(P_Node * m); int height()const; int width()const; void display(ostream &, int, int)const; friend ostream & operator <<(ostream & os, const Picture & p); friend Picture frame(const Picture & p); friend Picture operator & (const Picture & p, const Picture & q); friend Picture operator | (const Picture & p, const Picture & q); }; class String_Pic :public P_Node { friend class Picture; String_Pic(const char* const * arr, int n); ~String_Pic(); char** data; int size; int height()const; int width()const; void display(ostream &, int, int)const; }; class Frame_Pic :public P_Node { friend Picture frame(const Picture &); int height()const; int width()const; void display(ostream &, int, int)const; Frame_Pic(const Picture &); Picture p; }; class Vcat_Pic :public P_Node { friend Picture operator & (const Picture & n, const Picture & m); Vcat_Pic(const Picture & n, const Picture & m); int height()const; int width()const; void display(ostream &, int, int)const; Picture top, bottom; }; class Hcat_Pic :public P_Node { friend Picture operator | (const Picture & n, const Picture & m); Hcat_Pic(const Picture & n, const Picture & m); int height()const; int width()const; void display(ostream &, int, int)const; Picture left,right; }; Picture::Picture(const Picture & m) :p(m.p) { m.p->use++; } Picture::Picture(P_Node * m) : p(m){} Picture::~Picture() { if (--p->use == 0) delete p; } Picture& Picture::operator=(const Picture & q) { q.p->use++; if (--p->use == 0) delete p; p = q.p; return *this; } int Picture::height()const{ return p->height(); } int Picture::width()const { return p->width(); } void Picture::display(ostream & os, int n, int m)const { p->display(os, n, m); } Picture::Picture(const char* const * arr, int n) :p(new String_Pic(arr, n)){} P_Node::P_Node() :use(1){} String_Pic::String_Pic(const char * const * arr, int n) : data(new char*[n]), size(n) { for (int i = 0; i < n; ++i) { data[i] = new char[strlen(arr[i]) + 1]; strcpy_s(data[i],strlen(arr[i])+1,arr[i]); } } String_Pic::~String_Pic() { for (int i = 0; i < size; ++i) delete[]data[i]; delete[]data; } int String_Pic::height()const{ return size; } int String_Pic::width()const { int n = 0; for (int i = 0; i < size; ++i) n = max(n, strlen(data[i])); return n; } void String_Pic::display(ostream & os, int row, int width)const { int start = 0; if (row >= 0 && row < height()) { os << data[row]; start = strlen(data[row]); } pad(os, start, width); } int Frame_Pic::height()const{ return p.height() + 2; } int Frame_Pic::width()const{ return p.width() + 2; } void Frame_Pic::display(ostream& os, int row, int wd)const { if (row < 0 || row >= height()) { pad(os, 0, wd); } else { if ( 0 == row || row == height() - 1) { os << "+"; int i = p.width(); while (--i >= 0)os << "-"; os << "+"; } else { os << "|"; p.display(os, row - 1, p.width()); os << "|"; } pad(os, width(), wd); } } Frame_Pic::Frame_Pic(const Picture & m) :p(m){} Picture frame(const Picture & m) { return new Frame_Pic(m); } Vcat_Pic::Vcat_Pic(const Picture & t, const Picture & b) : top(t), bottom(b){} Hcat_Pic::Hcat_Pic(const Picture & l, const Picture & r) : left(l),right(r){} Picture operator &(const Picture & n, const Picture & m) { return new Vcat_Pic(n, m); } Picture operator |(const Picture & n, const Picture & m) { return new Hcat_Pic(n, m); } int Vcat_Pic::height()const{ return top.height() + bottom.height(); } int Vcat_Pic::width()const{ return max(top.width(), bottom.width()); } int Hcat_Pic::height()const{ return max(left.height(), right.height()); } int Hcat_Pic::width()const{ return left.width()+ right.width(); } void Vcat_Pic::display(ostream& os, int row, int wd)const { if (row >= 0 && row < top.height()) top.display(os, row, wd); else { if (row < top.height() + bottom.height()) bottom.display(os, row - top.height(), wd); else pad(os, 0, wd); } } void Hcat_Pic::display(ostream & os, int row, int wd)const { left.display(os, row, left.width()); right.display(os, row, right.width()); pad(os, width(), wd); } void P_Node::pad(ostream & os, int x, int y)const { for (int i = x; i < y; ++i) os << " "; } ostream & operator <<(ostream & os, const Picture & p) { int ht = p.height(); for (int i = 0; i < ht; ++i) { p.display(os, i, 0); os << endl;} return os; } #endif
#include"NewPicture.h" #include<iostream> using namespace std; int main() { char * init[] = { "Summer", "love", "Xieweizhong" }; Picture p(init, 3); cout << p << endl; cout << frame((p | frame(p)) | (p | frame(p))) << endl; cout << frame((p & frame(p)) | (p | frame(p))) << endl; cout << frame((p | frame(p)) | (p & frame(p))) << endl; cout << frame((p & frame(p)) | (p & frame(p))) << endl; cout << frame((p | frame(p)) & (p | frame(p))) << endl; cout << frame((p & frame(p)) & (p | frame(p))) << endl; cout << frame((p | frame(p)) & (p & frame(p))) << endl; cout << frame((p & frame(p)) & (p & frame(p))) << endl; return 0; }
原文:http://blog.csdn.net/shiwazone/article/details/45229617