读书笔记:10章一个课堂练习的分析(下)2

C++沉思录第十章读书笔记(下)2[@more@]

第十章:一个课堂练习的分析(下)2

10-1.4 显示图象

我们很可能使用一个反映了Picture结构的算法来打印该Picture.典型方式是分行打印字符串。假设我们打算这么干,这种情况下如果实现显示Frame_Pic的函数呢?很难办。(为什么?)。因为需要在该图象的每一行中打印边框部分。所以显示操作功能不够完美。

如果希望能够控制每一行的首尾形态,则必须能够打印指定图象的某一行(不带换行符)。只要能作到这点,加筐的操作就简单了,首先打印顶筐,然后图象的每一行,打印左边框,然后是图象行,再后是右边筐,最后打印底框。

仔细分析这个过程,我们需要确定一副图象的高度和宽度。

完了吗?假设我们要显示一个String_Pic,我们希望每一行显示完毕后立即换行,没有必要在尾部填充多余的空格。但是当 包含String_PicFrame_Pic时,必须在该String_Pic的每一行尾部填补适量的空格。

于是,显示操作需要两个参数:打印的行数和最小宽度。每一行都会填补必要的空格来满足最小宽度的要求。应该还有一个参数:输出的目标文件。

P_Node的派生类将会用到我们新增的heignt, width, display函数。然而我们把这些设置为private 这样普通用户不能使用它们。这个想法可以保证Picture类的节口不能使用其函数,付出代价,所有的P_Node派生出来的新类成为Picture的友员。

class Picture{

//和前面一样

friend class String_Pic;

friend class Frame_Pic;

friend class Hcat_Pic;

friend class Vcat_Pic;

private:

Picture(P_Node*);

int height() const; //新增的

int width() const; //新增的

int display(ostream&, int, int) const; // 新增的

P_Node* p;

};

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);

}

现在考虑operator<<

ostream& operator<

{

int ht = picture.height(0;

for(int i=0; i

picture.display(os, i, o);

os<

}

return os;

}

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; //新增的

private:

int use;

};

其派生类都加上,不要带0

int P_node::max(int x, int y)

{

return x>y?x:y;

}

int String_Pic::height() const

{

return size;

}

int String_Pic::width() const

{

int n= 0;

for(int i= 0; i

n = max(n.strlen(data[i]));

}

return n;

}

static void pad(ostream& os, int x, int y)

{

for(int i =x; i

os << " ";

}

void

String_Pic::display(ostream& os, int row, int weith) const

{

int start = 0;

if(row >= 0 && row

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 we) const

{

if(row < 0 || row >= height()) {

// 越界

pad(os, 0, wd);

}else {

if(row = 0 ||row ==hieght()-1) {

//顶筐和低筐

os << "+";

int i = p.width();

while(--i >= 0)

os << "-";

os <

}else {

//内部行

os << "|";

p.display(os, row-1, p.width());

os << "|"

}

pad(os, width(0, wd);

}

}

//打印连接后的图象

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(0, reght.height());

}

int HCat_Pic::width() const

{

return left.width() + reght.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

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, reow, right.width());

pad(os, width(), wd);

}

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/409557/viewspace-892092/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/409557/viewspace-892092/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值