返回信息流☆─────────────────────────────────────☆
jkice (MeeMoo) 于 (Tue May 4 20:44:10 2010) 提到:
在看accelerated c++,第14章说引用计数句柄,这个类的赋值操作符定义如下:
template <class T>
Ref_handle<T>& Ref_handle<T>::operator=(const Ref_handle& rhs)
{
++*rhs.refptr;
if(--*refptr == 0) {
delete refptr;
delete p;
}
refptr = rhs.refptr;
p = rhs.p;
return *this;
}
书上说通过先自增右操作数的引用计数,可以防止自我赋值,在C++ Primer也是这样说的,但是没有解释,我也没想明白,大家指教一下,谢谢
☆─────────────────────────────────────☆
a206206 (每天都被人超级鄙视的寂寞帝和悲剧帝) 于 (Tue May 4 20:46:32 2010) 提到:
我也没明白你说什么。。。。
☆─────────────────────────────────────☆
jkice (MeeMoo) 于 (Tue May 4 20:57:14 2010) 提到:
【 在 a206206 的大作中提到: 】
: 我也没明白你说什么。。。。
: --
: 黑暗凝集灵魂,堕落方能自由
: ...................
定义一个类,当指针用,当复制这个类的对象时,并不复制底层的数据,即可以有多个对象指向相同的底层数据。这个类有复制构造函数和重载赋值操作符,上面是重载的赋值操作符,其中refptr是个计数,记录的是指向这个底层数据的指针(就是这个类的对象)有多少个。书上说先给右操作数的计数加一可以防止自我赋值,这个我没懂。
呃。。。我觉得我还是没说明白。。。
☆─────────────────────────────────────☆
a206206 (每天都被人超级鄙视的寂寞帝和悲剧帝) 于 (Tue May 4 21:25:54 2010) 提到:
就是说比如a=a,是可以的,这时候指针计数器是1,但是自减了以后就是0,而他其实还有一个对象a,所以先自增就可以避免错误,如果是a=b,那么指向b类的尔计数器就躲一个,恩。
☆─────────────────────────────────────☆
jkice (Bamboo) 于 (Tue May 4 21:31:45 2010) 提到:
【 在 a206206 的大作中提到: 】
: 就是说比如a=a,是可以的,这时候指针计数器是1,但是自减了以后就是0,而他其实还有一个对象a,所以先自增就可以避免错误,如果是a=b,那么指向b类的计数器就多一个,恩。
: --
: 黑暗凝集灵魂,堕落方能自由
: ...................
那a=a不是自我赋值吗?
☆─────────────────────────────────────☆
a206206 (每天都被人超级鄙视的寂寞帝和悲剧帝) 于 (Tue May 4 21:33:59 2010) 提到:
【 在 jkice 的大作中提到: 】
: 那a=a不是自我赋值吗?
是啊,那是合法的操作啊
☆─────────────────────────────────────☆
jkice (Bamboo) 于 (Tue May 4 21:46:18 2010) 提到:
【 在 a206206 的大作中提到: 】
:
: 【 在 jkice 的大作中提到: 】
: : 那a=a不是自我赋值吗?
: ...................
但是是要防止自我赋值,是不是我理解有问题,其他的赋值操作符都是通过*this != rhs来判断是不是自我赋值,要是是自我赋值就什么都不做,return *this,要是不是就先将左操作数的 数据成员delete掉,之后把右操作数赋给左操作数。
☆─────────────────────────────────────☆
a206206 (每天都被人超级鄙视的寂寞帝和悲剧帝) 于 (Tue May 4 22:34:55 2010) 提到:
为什么要防止,赋值确实会消除左值,但是因为他传的是this的一个拷贝,所以是可以的,但是如果有指针,就不能这么用了
☆─────────────────────────────────────☆
Drust0101 (Drust.X) 于 (Thu May 6 12:32:51 2010) 提到:
a=a时
++*rhs.refptr; 加1
if(--*refptr == 0) 又减1,
所以没变,没有自我增值
再 refptr = rhs.refptr; 赋值没问题
如果先 refptr = rhs.refptr;
再 ++*rhs.refptr;
++refptr;
则a=a时refptr增加了,自我增值了,a=a时应该不增加引用计数
不知道理解的对不对。。。
☆─────────────────────────────────────☆
jkice (Bamboo) 于 (Thu May 6 13:38:53 2010) 提到:
【 在 Drust0101 的大作中提到: 】
: a=a时
: ++*rhs.refptr; 加1
: if(--*refptr == 0) 又减1,
: ...................
是不是说共享底层数据的赋值只和引用计数有关,赋值就是将引用计数加1,但是自我赋值不用加这个1,如果不是自我赋值,就看左操作数是不是最后一个指向底层数据的,如果是就先delete,之后在赋值,如果不是,就引用计数加1,再赋值。对吗?
☆─────────────────────────────────────☆
taps (Awesome) 于 (Thu May 6 14:00:30 2010) 提到:
1.无论怎样,左操作数-1和右操作数+1都是必要的操作。
2.这段代码强调的是用 “先将右操作数引用计数+1再将左操作数引用计数-1”,强调的是顺序,+1和-1都是必要操作,之所以有先后问题之存在于,-1的时候需要判断是否需要释放内存。如果某块内存只有一个引用计数指针指向它,那么对它的自我赋值,-1先执行将会删除内存。
【 在 jkice 的大作中提到: 】
: 是不是说共享底层数据的赋值只和引用计数有关,赋值就是将引用计数加1,但是自我赋值不用加这个1,如果不是自我赋值,就看左操作数是不是最后一个指向底层数据的,如果是就先delete,之后在赋值,如果不是,就引用计数加1,再赋值。对吗?
☆─────────────────────────────────────☆
jkice (Bamboo) 于 (Thu May 6 19:50:49 2010) 提到:
【 在 taps 的大作中提到: 】
: 1.无论怎样,左操作数-1和右操作数+1都是必要的操作。
: 2.这段代码强调的是用 “先将右操作数引用计数+1再将左操作数引用计数-1”,强调的是顺序,+1和-1都是必要操作,之所以有先后问题之存在于,-1的时候需要判断是否需要释放内存。如果某块内存只有一个引用计数指针指向它,那么对它的自我赋值,-1先执行将会删除内存。
: 【 在 jkice 的大作中提到: 】
: ...................
是不是这样,假设两个指针lhs和rhs,底层数据是data,当lhs!=rhs时,因为要将rhs赋给一个其他值,所以就需要将prt2的引用计数加1。之后检查左操作数是否是最后一个指向data的,要是是就先delete,之后再赋值。如果lhs==rhs,那么一加一减就没变,--*refptr就不可能为0,不为零就不会delete,只是后边的语句将lhs重新赋了自己的值,而引用计数没变,所以没有自我赋值。
☆─────────────────────────────────────☆
taps (Awesome) 于 (Fri May 7 08:57:10 2010) 提到:
是的
【 在 jkice 的大作中提到: 】
: 是不是这样,假设两个指针lhs和rhs,底层数据是data,当lhs!=rhs时,因为要将rhs赋给一个其他值,所以就需要将prt2的引用计数加1。之后检查左操作数是否是最后一个指向data的,要是是就先delete,之后再赋值。如果lhs==rhs,那么一加一减就没变,--*refptr就不可能为0,不为零就不会delete,只是后边的语句将lhs重新赋了自己的值,而引用计数没变,所以没有自我赋值。
这是一条镜像帖。来源:北邮人论坛 / cpp / #39019同步于 2010/5/8
CPP机器人发帖
[合集] 求助一个c++引用计数句柄的赋值操作符问题
jokerlee
2010/5/8镜像同步0 回复
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。