欢迎来到山村网

一个课堂打印案例分析

2019-03-02 09:43:29浏览:779 来源:山村网   
核心摘要:作者构造了Picture类,汇总需求细节,见招拆招,尤其在接口设计这一节里,把自己当成客户,跟自己一问一答(我希望有些什么操作

作者构造了Picture类,汇总需求细节,见招拆招,尤其在“接口设计”这一节里,把自己当成客户,跟自己一问一答(“我希望有些什么操作,如何表述这些操作?”),逐步分析不断复杂的需求,然后抽象出接口,其中不乏作者的经验之谈:要想决定具体操作的形式,有一个好办法,就是试着使用这些操作,从使用的例子推导出操作的定义形式要比从头苦思冥想地发明这些操作容易得多。

  1、最初需求是打印如下文字:

  Paris

  in the

  Spring

  2、构造的Picture类,只需要一个构造函数和一个输出即可完成,如果打印如下文字:

  +-------+

  |Paris |

  |in the |

  |Spring|

  +-------+

  3、如果使用C式的过程代码,需要做些打印内容的改变可以完成,作者为Picture类添加了一个frame(Picture&)来完成,如果打印内容改变了,我想C式代码作者就会抓头皮了:

  Paris +-------+

  in the |Paris |

  Spring|in the |

  |Spring|

  +-------+

  4、Picture类便有了 Picture operator |(const Picture&, const Picture&) 接口,用字符‘|’做两个Picture对象的横向合并,用Picture operator &(const Picture&,const Picture&)接口,用字符‘&’做纵向合并,当我们需要打印如下文字的时候:

  +--------------+

  |+------+ |

  ||Paris | |

  ||in the| |

  ||Spring| |

  |+------+ |

  |Paris +------+|

  |in the|Paris ||

  |Spring|in the||

  | |Spring||

  | +------+|

  +--------------+

  我们只需要一句 cout << frame(frame(p) & (p | frame(p))) << endl即可完成。

  下面是Picture类的源码(原书代码中有些许错误,均做过修改和测试):

  1 #include <iostream>

  2

  3

  4 using namespace std;

  5

  6 class Picture

  7 {

  8 friend Picture frame(const Picture&); //加框

  9 friend Picture operator&(const Picture&, const Picture&); //纵向合并

  10 friend Picture operator|(const Picture&, const Picture&); //横向合并

  11 friend ostream& operator << (ostream& o, const Picture& p);

  12 private:

  13 int height, width;

  14 char* data;

  15 char& position(int row, int col){

  16 return data[row * width + col];

  17 };

  18 char position(int row, int col) const{

  19 return data[row * width + col];

  20 };

  21 void copyblock(int,int,const Picture&);

  22 public:

  23 Picture() : height(0),width(0),data(0){};

  24 Picture(const char* const*, int);

  25 Picture(const Picture& );

  26 ~Picture();

  27 Picture& operator=(const Picture&);

  28 static int max(int m, int n)

  29 {

  30 return m > n ? m : n;

  31 };

  32 void init(int h, int w);

  33 void clear(int , int ,int ,int );

  34 };

  35

  36 ostream&

  37 operator << (ostream& o, const Picture& p)

  38 {

  39 for(int i = 0; i < p.height; ++i)

  40 {

  41 for(int j =0; j < p.width; ++j)

  42 o << p.position(i,j);

  43 o << endl;

  44 }

  45 return o;

  46 };

  47

  48

  49 void Picture::init(int h, int w)

  50 {

  51 height = h;

  52 width = w;

  53 data = new char[height * width];

  54 };

  55

  56 Picture::Picture(const char* const* array, int n)

  57 {

  58 int w = 0;

  59 int i ;

  60 for(i = 0; i < n; i++)

  61 w = Picture::max(w, strlen(array[i]));

  62 init(n,w);

  63 for(i = 0; i < n; i++)

  64 {

  65 const char* src = array[i];

  66 int len = strlen(src);

  67 int j = 0;

  68 while(j < len)

  69 {

  70 position(i,j) = src[j];

  71 ++j;

  72 }

  73 while(j < width)

  74 {

  75 position(i, j) = ' ';

  76 ++j;

  77 }

  78 }

  79 }

  80

  81 Picture::Picture(const Picture& p):

  82 height(p.height), width(p.width),

  83 data(new char[p.height * p.width])

  84 {

  85 copyblock(0,0,p);

  86 }

  87

  88 Picture::~Picture()

  89 {

  90 delete []data;

  91 }

  92

  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 void Picture::copyblock(int row,int col,const Picture& p)

  105 {

  106 for(int i =0; i < p.height; ++i)

  107 {

  108 for(int j =0; j < p.width; ++j)

  109 position(i+row, j+col) = p.position(i,j);

  110 }

  111 }

  112

  113 void Picture::clear(int h1,int w1,int h2,int w2)

  114 {

  115 for(int r = h1; r < h2; ++r)

  116 for(int c = w1; c < w2; ++c)

  117 position(r,c) = ' ';

  118 }

  119

  120 Picture frame(const Picture& p)

  121 {

  122 Picture r;

  123 r.init(p.height + 2, p.width + 2);

  124 for(int i = 1; i < r.height -1; ++i)

  125 {

  126 r.position(i,0) = '|';

  127 r.position(i, r.width - 1) = '|';

  128 }

  129 for(int j = 1; j < r.width - 1; ++j)

  130 {

  131 r.position(0, j) = '-';

  132 r.position(r.height - 1, j) = '-';

  133 }

  134 r.position(0, 0) = '+';

  135 r.position(0, r.width-1) = '+';

  136 r.position(r.height-1, 0)= '+';

  137 r.position(r.height-1,r.width-1)='+';

  138 r.copyblock(1,1,p);

  139 return r;

  140 }

  141

  142 Picture operator&(const Picture& p, const Picture& q)

  143 {

  144 Picture r;

  145 r.init(p.height + q.height, Picture::max(p.width ,q.width));

  146 r.clear(0,p.width,p.height,r.width);

  147 r.clear(p.height,q.width,r.height,r.width);

  148 r.copyblock(0,0,p);

  149 r.copyblock(p.height,0,q);

  150 return r;

  151 }

  152

  153 Picture operator|(const Picture& p, const Picture& q)

  154 {

  155 Picture r;

  156 r.init(Picture::max(p.height,q.height),p.width + q.width);

  157 r.clear(p.height,0,r.height,q.width);

  158 r.clear(q.height,p.width,r.height,r.width);

  159 r.copyblock(0,0,p);

  160 r.copyblock(0,p.width,q);

  161 return r;

  162 }

  测试代码:

  1 char *init[]= {"Paris","in the","Spring"};

  2 Picture p(init,3);

  3 cout << frame(frame(p) & (p | frame(p))) << endl;

(责任编辑:豆豆)
下一篇:

一个有关随机函数rand()的小程序

上一篇:

cctype 头文件定义函数实例

  • 信息二维码

    手机看新闻

  • 分享到
打赏
免责声明
• 
本文仅代表作者个人观点,本站未对其内容进行核实,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,作者需自行承担相应责任。涉及到版权或其他问题,请及时联系我们 xfptx@outlook.com