c++笔记之句柄类

上一篇 / 下一篇  2012-09-11 14:21:50 / 个人分类:C++

[(}:Rr-Y{B7@0  句柄类存储和管理基类指针。指针所指的对象的类型可以变化,即可以指向基类对戏那个又可以指向派生类类型对象。用户通过句柄类访问继承层次的操 纵。因为句柄类使用指针执行操作,虚成员的行为将在运行时根据句柄实际绑定的对象的类型而变化。因此,句柄的用户可以获得动态行为但无需操心指针的管理。51Testing软件测试网N$VF2J%fsg

51Testing软件测试网q f8^U2\GzYd"?

  包装了继承层次的句柄有两个重要的设计考虑因素51Testing软件测试网^H'S XS1|k~0z5fx

.QZ!N1[{N z{5E0  1、像对任何保存指针的类一样。必须确定对复制控制做些什么。包装了继承层次的句柄通常表现的像一个只能指针或像一个值。51Testing软件测试网Py3Z2V4\w(g)qn;b

51Testing软件测试网5~"A6Y]Hz3L(^

  2、句柄类决定句柄接口屏蔽还是不屏蔽继承层次,如果不屏蔽继承层次,用户必须了解和使用基本层次中的对象。

\U6P(Z7Sk051Testing软件测试网1LvJxV D I

  我们将定义名为Sale_item的指针型句柄类,表示Item_base层次,Sales_item的用户将像使用指针一样使用它:将用户Sals_item绑定到Item_base类型的对象并使用*和—>操作符执行Item_base的操作。51Testing软件测试网!Y\Q9f'R!l(~v$v

RT3r$]!T5G0  例如:Sale_item item(Bulk_item("0-102-34529",35,4,43));51Testing软件测试网x.} i| dE`e'R

51Testing软件测试网%z K*J1n9\7^"{!X

  item->net_price();//item像是指针一样。

1X+}X/sW \/_051Testing软件测试网DG1Yj,p8h'u%F2zZ&G

  用户可以不必管理句柄指向的对象,Sales_item类将完成这部分工作。当用户通过Sales_item类对像那个调用函数式,将获得多态行为。51Testing软件测试网 A)xQ d ~:H

Eq d)q-rO0   Sales_item类将有两个数据成员,都是指针,一个指针将指向Item_base对戏那个,而另一个将指向使用计数,Item_base指针可以 指向Item_base 也可以指向Item_base 派生类类型的对象,通过指向使用计数,多个Sale_item对象可以共享同一个计数器。

h}l iGf*V0

K#m Hcx2Q}0class Sales_item
mW,J'u5@7yH X0{
2[LI7g,Z0public:
1RF oOJoU0 Sales_item():p(0),use(new size_t(1)){}51Testing软件测试网 M+?x*hsv0a7U]
 Sales_item(const Item_base&);
~Pt O(b0 Sales_item(const Sales_item &i):p(i.p),use(i.use)51Testing软件测试网7L,Rq)c9j6S S{@
 {51Testing软件测试网+Z:u-s w8_D
 ++*use; 
K*I @R;Byns0 }
-U1zt-|bG"}7[ {M0 ~Sales_item(){dec_use();};
H3Wa7o!{)K0 Sales_item& perator=(const Sales_item&);51Testing软件测试网 X"?.m[+~](i
 const Item_base *operator->()const{if(p) return p;}51Testing软件测试网VO/kBMx
 const Item_base&  operator*()const{if(p) return *p;}
*^BuQv1jo9F0private:
)a#x0]9N0E il1U0 Item_base *p;51Testing软件测试网C_1Q8ZSY@^
 size_t *use;
Nh/XWT0 void dec_use()51Testing软件测试网%Z-ZnA \Jew
 {if(--*use==0){delete p;delete use;}}
51Testing软件测试网ejoTsfO!r8T.G|

~3zkS0jc$V,Y6f @8w0};51Testing软件测试网1mQ.Qh6|?x i

+wC0iU4fM H(G8b:n0Sales_item& Sales_item::operator=(const Sales_item& i)
5\'W*wq q8KE7fV0{51Testing软件测试网 {~ J'Cn:FO m
    ++*i.use;51Testing软件测试网9Fa3X)Wy|
 dec_use();
zBC\Qi5K0 p=i.p;51Testing软件测试网G(yKJ8e |s)u
 use=i.use;51Testing软件测试网IyN3S?/]
 return *this;

3YQL3|P0

v$^-X ^+M A0
KC5{@F*v{0}
51Testing软件测试网~5Z%c2pz(CZ$X*X

t Cr)wj0   要实现Item_base对象的构造函数,必须首先解决一个问题:我们不知道给予构造函数的对象的实际类型,我们知道他是一个Item_base对象或 者是它的派生类的对象,句柄类经常需要在不知道对象的确切类型是分配一直对象的新副本。解决这个问题的通用方法是定义虚操作进行赋值,我们称将该操作 clone51Testing软件测试网8?!H;eC jB

class Item_base
?0zC;s1q k [-c0{51Testing软件测试网6V"nenx
public:51Testing软件测试网e h4\ N/I_ c
 virtual Item_base* clone()const51Testing软件测试网%ifhDW,{`8i`)q5}
 {51Testing软件测试网Dl)[ X$w"N
 return new Item_base(*this);51Testing软件测试网z&g\5s&u[Vb2N:x~
 }51Testing软件测试网~QU&R2ZO Tb*VF
};

LK1uA} jc"n0class Bulk_item:public Item_base
$~ ^,e&`;V0{

&e$G+ly$^P.y*t*Y;m0

-R q}[T{v1S I6{9x0public:
nt!EC$O` I0 Bulk_item* clont()const
~%X9yy `5q0 {
^0H5bOb0 return new Bulk_item(*this);
-B'es(|e a"ABK0 }

LA5^ E A}l[!w\M051Testing软件测试网!kb$V)P%^(r;_ C

};

/M0?#b3EhY#mX0
Sales_item::Sales_item(const Item_base &item):p(item.clone()),use(new size_t(1)){}

}LeN$@]0  像默认构造函数一样,这个构造函数分配并初始化使用计数,它调用形参的clone产生那个对象的虚副本,如果实参是Item_base对象,则运行Item_base的clone函数。如果是Bulk_item对象则执行它的clone函数。

7sM s6K$?G0

TAG:

 

评分:0

我来说两句

Open Toolbar