哈哈,没想到n年之后(夸张点),我竟然自己来回答自己当年提的问题,有意思,我尽可能详细的讲
首先,你要明白,建立不同的HasPtr对象(假设不通过复制构造函数),每个HasPtr对象所拥有的U_Ptr所指向的内存是不同的,假如你建立了
int* p=new int(1);
int* q=new int(2);
HasPtr hasptr1(p,3);
HasPtr hasptr2(q,4);
那么这两个对象所拥有的U_Ptr所指向的内存是不同的,因为HasPtr构造函数的ptr成员是通过new U_Ptr来分配的
使用智能指针的目的一般是为了共享同一个内存对象,避免了额外开销
现在,假设通过赋值操作,比如hasptr3=hasptr5=hasptr1,hasptr4=hasptr6=hasptr8=hasptr2;
那么现在有三个hasptr对象共享了hasptr1的U_Ptr成员的ip成员,有四个hasptr对象共享了hasptr2的U_Ptr成员的ip成员
那么现在假设有hasptr1=hasptr2,那么,因为hasptr1现在通过赋值要共享hasptr2了,所以是不是现在应该是hasptr3,hasptr5共享了他们的U_Ptr的ip成员,即那个p指向的1,他们的引用计数现在由3变为2,hasptr2,hasptr4,hasptr6,hasptr8,hasptr1共享了他们的U_Ptr的ip成员,即q指向的2,他们的引用计数现在由4变为5了,对吧,现在看代码
if(++rhs.ptr->use)
因为hasptr1=hasptr2,所以这条语句是不是使hasptr2的使用计数由4变为了5(hasptr2多了共享)
if(--ptr->use==0)
因为hasptr1=hasptr2,所以这条语句是不是使hasptr1的使用计数由3变为了2(hasptr1减少了共享)
接着进行下面的代码
你问 if语句中是如果use==0了就调用析构函数释放,那么如果自减之后依然不是0呢,就不会调用析构函数,但是依然会执行后面的prt=rhs.ptr。。。有什么意思?
我的举例就是这种情况,自减之后不为0,但是hasptr2的使用计数由4变为了5,hasptr1的使用计数由3变为了2,这是不是智能指针的作用呢,跟踪有多少个对象共享,还有,这里的ptr和rhs.ptr不是同一个对象,rhs.ptr是hasptr2的ptr,ptr是hasptr1的ptr
还有截图上说的先让rhs.ptr自加是为了防止自身赋值,那请问是怎么样防止的?
假设现在没有hasptr1=hasptr2,而是hasptr2=hasptr2,那么你说有多少个对象共享hasptr2的U_Ptr的ip值呢,还是4个对不对,对非hasptr2(即hasptr1,引用计数应由4变为了5,对hasptr2=hasptr2,应该还是为4,不变)
看代码,先if(++rhs.ptr->use),这样把hasptr2的计数加1,if(--ptr->use==0)因为都是为hasptr2,所以这里的赋值语句的ptr和rhs.ptr是同一个,--ptr->use是hasptr2的引用计数减1,(加1减1后,还是4)这样是不是防止了因为自身赋值而错误的把一切用hasptr2赋值都使引用计数由4变为了5,如果使用计数为0,就调用了析构函数了
不懂可以继续问
还有,非常感谢玩出来的代码以前对我的帮助