程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> 一個課堂打印案例分析

一個課堂打印案例分析

編輯:更多關於編程

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

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved