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

C++沉思录第十章读书笔记1[@more@]

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

缺陷:浪费太多空间,而且本质上非常不灵活。

新设计方案与8章中所设计的表达式树非常相似在类层次中反映出我们所操作的图象的结构,并将此结构保留下来以待今后所用。此外,我们还提供了一个句柄类,一则可以将我们使用继承的实现细节隐藏起来,二则可以省去用户处理内存管理的麻烦。

10-1策略

9章方案最大弊端图象对象一旦生成,其结构信息立刻就丢失(为什么)。假如我们采用不同的策略,尽可能地保留结构信息,结果会怎么样?我们又该怎么做呢?能有什么好处?

第一个结论:就是我们可以存储几种不同的图象。一副图象的结构信息中最明显的方面就是一其构成方式:是从字符串中直接生成,还是加筐形成的,还是横向或者纵向连接而成的。

第二个结论:不必复制图象的内容了,假如我们将图象x加边框形成图象y,此操作并没有改动x,这就是说, y可以直接利用x而无需复制其内容。

Picture类中应包含一个指向其他类对象的指针;该对象应该表明其确切的图象种类。使用继承来组织和区分各种图象,就会产生这样的结构,Picture类包含一个(私有的)指针,指向一个我们称之为P_Node的类,这是一个抽象基类,有以下派生类。

String_Pic, 直接由字符串数组生成

Framed_Pic,

Hcat_Pic

Vcat_Pic

Picture P_Node类将协同解决内存分配的问题。

10-1-1 方案

class P_Node{};

class Frame_Pic:public P_Node{};

class String_Pic:public P_Node{};

class VCat_Pic:public P_Node{};

class Hcat_Pic:public P_Node{}

class P_Node;

class Picture {

friend ostream& operator<

friend Picture frame(const Picture&);

friend Picture operator&(const Picture&, const Picture&);

friend Picture operator&|(const Picture&, const Picture&);

public:

Picture();

Picture(const char* const*, int);

Picture(const Picture&);

~Picture();

Picture& operator=(const Picture&);

private:

P_Node* p;

};

10-1-2 内存分配

多个Pictuer可以指向同一个P_Node,应该引用计数。

class P_Node {

friend class Picture;

private:

int use;

};

Picture::Picture(const Picture& orig):p(orig.p)

{

orig.p->use++;

};

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;

}

class P_Node {

friend class Picture;

protected:

P_Node();

virtual ~P_Node(); //为什么

private:

int use;

};

P_Node::~P_Node() {}

P_Node::P_Node():use(1) {}

10-1-3 结构构造

如何构造表示不同图象的Picture对象的时候了?

我们已经决定构造函数生成一个String_Pic对象,并将其地址存储在Picture中。

Picture:Picture(const char* const* str, int n):

p(new String_pic(str, n)) {}

class String_Pic: public P_Node {

friend class Picture;

String_Pic(const char* const*, int);

~String_Pic();

char** data;

int size;

};

String_Pic::String_Pic(const char* const* p, int n):

Data(new char* [n]), size(n)

{

fir(int i = 0; i < n; i++) {

data[i] = new char[strlen(p[i])+1];

strcpy(data[i], p[i]);

}

}

String_Pic::~String_Pic()

{

for(int i = 0; i < size; i++)

delete[] data[i];

delete [] data;

}

class Frame_Pic:public P_Node

{

friend Picture frame(const Picture&);

Frame_Pic(const Picture&);

Picture p; //为什么?

}

Frame_Pic::Frame_Pic(const Picture& pic):p(pic) {}

Picture frame(const Picture& pic)

{

Frame_Pic* p = new Frame_Pic(pic);

// 现在如何?

}

创建了指针p,指向新创建的Frame_Pic对象,应当如何将这个指针加入一个Picture中,以便把这个Picture对象返回给用户呢?

可以回头修补,给Picture类增加一个私有构造函数。(为什么私有)。

Picture::Picture(P_Node* p_nide):p(p_node) {}

现在可以完成frame函数了。

Picture frame(const Picture&pic)

{

return new Frame_Pic(pic);

}

class Vcat_Pic: public P_Node {

friend Picture operator&

(const Picture&, const Picture&);

Vcat_Pic(const Picture&, const Picture&);

Picture top, bottom;

};

class Hcat_Pic:public P_Node {

friend Picture operator|

(const Picture&, const Picture&);

Hcat_Pic(const Picture&, const Picture&);

Picture left, right;

};

Vcat_Pic::Vcat_Pic(const Picture& t, const Picture& b) :

top(t), bottom(b) {}

Picature 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) {}

Picture operator|(const Picture& l , const Picture& r)

{

return new Hat_Pic(l, r);

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值