虽然还不是很懂啊,但却很有意思。
下面把辛辛苦苦打的代码贴出来,大家一起学习。
下面是 Picture.h :
#include<iostream>
using namespace std;
class P_Node{
friend class Picture;
protected:
P_Node();
virtual ~P_Node();
virtual int height() const=0;
virtual int width() const=0;
virtual void display
(ostream&,int,int)const=0;
//int max(int,int);
private:
int use;
};
class Picture{
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&);
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&);
private:
Picture(P_Node*);
int height() const;
int width() const;
void display(ostream&,int,int) const;
P_Node* p;
};
class String_Pic:public P_Node{
friend class Picture;
String_Pic(const char* const*,int);
~String_Pic();
int height() const;
int width() const;
void display(ostream&,int,int) const;
char** data;
int size;
};
class Frame_Pic:public P_Node{
friend Picture frame(const Picture&);
Frame_Pic(const Picture&);
int height() const;
int width() const;
void display(ostream&,int,int) const;
Picture p;
};
class VCat_Pic:public P_Node{
friend Picture operator&
(const Picture&,const Picture&);
VCat_Pic(const Picture&,const Picture&);
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&,const Picture&);
Hcat_Pic(const Picture&,const Picture&);
int height() const;
int width() const;
void display(ostream&,int,int) const;
Picture left,right;
};
下面是 Picture.cpp :
#include"Picture.h"
#include<iostream>
#include<cstring>
using namespace std;
P_Node::~P_Node(){}
P_Node::P_Node():use(1){}
static void pad(ostream& os,int x,int y)
{
for(int i=x;i<y;i++)
os<<" ";
}
int max(int x,int y)
{
return x>y?x:y;
}
Picture::Picture(const char* const* str,int n):
p(new String_Pic(str,n)){}
Picture::Picture(const Picture& orig):p(orig.p)
{
orig.p->use++;
};
Picture::Picture(P_Node* p_node):p(p_node){}
Picture::~Picture()
{
if(--p->use==0)
delete p;
}
Picture& Picture::operator=(const Picture& orig)
{
orig.p->use++;
if(--p->use==0)
delete p;
p=orig.p;
return *this;
}
int Picture::height() const
{
return p->height();
}
int Picture::width() const
{
return p->width();
}
void Picture::display(ostream& o,int x,int y)const
{
p->display(o,x,y);
}
ostream& operator<<(ostream& os,const Picture& picture)
{
int ht=picture.height();
for(int i=0;i<ht;i++){
picture.display(os,i,0);
os<<endl;
}
return os;
}
String_Pic::String_Pic(const char* const* p,int n):
data(new char* [n]),size(n)
{
for(int i=0;i<n;i++){
data[i]=new char[strlen(p[i])+1];
strcpy(data[i],p[i]);
}
}
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);
}
String_Pic::~String_Pic()
{
for(int i=0;i<size;i++)
delete[] data[i];
delete[] data;
}
Frame_Pic::Frame_Pic(const Picture& pic):p(pic){}
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(row==0||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);
}
}
Picture frame(const Picture& pic)
{
return new Frame_Pic(pic);
}
VCat_Pic::VCat_Pic(const Picture& t,const Picture& b):
top(t),bottom(b){}
int VCat_Pic::height()const
{
return top.height()+bottom.height();
}
int VCat_Pic::width()const
{
return max(top.width(),bottom.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);
}
Picture operator&(const Picture& t,const Picture& b)
{
return new VCat_Pic(t,b);
}
Hcat_Pic::Hcat_Pic(const Picture& l,const Picture& r):
left(l),right(r){}
int Hcat_Pic::height()const
{
return max(left.height(),right.height());
}
int Hcat_Pic::width()const
{
return left.width()+right.width();
}
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);
}
Picture operator|(const Picture& l,const Picture& r)
{
return new Hcat_Pic(l,r);
}
下面是 test.cpp :
#include<iostream>
#include<cstring>
#include"Picture.h"
using namespace std;
char *init[]={"Paris","in the","Spring"};
int main()
{
Picture p(init,3);
cout<<p<<endl;
Picture q=frame(p);
cout<<q<<endl;
cout<<(q&(p|q))<<endl;
cout<<frame(p|p)<<endl;
cout<<frame(q|q)<<endl;
cout<<(p&p)<<endl;
cout<<(q&q)<<endl;
cout<<frame(p&p)<<endl;
cout<<frame(frame(q&q)|frame(p&p))<<endl;
return 0;
}