一個課堂列印案例分析

來源:互聯網
上載者:User

作者構造了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;

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.