c++有两种实现引用计数的经典方法,现介绍第一种
- #include <iostream>
-
using namespace std;
-
-
class U_Ptr
-
{
-
private:
-
friend class HasPtr;
-
int *ip;
-
size_t use;
-
U_Ptr(int *p):ip(p), use(1) { }
-
~U_Ptr()
-
{
-
delete ip;
-
}
-
-
};
-
-
class HasPtr
-
{
-
public:
-
HasPtr(int *p, int v):ptr(new U_Ptr(p)), val(v) { };
-
HasPtr(const HasPtr &orig):ptr(orig.ptr), val(orig.val)
-
{
-
++ptr->use;
-
}
-
HasPtr& operator=(const HasPtr& rhs)
-
{
-
++rhs.ptr->use;
-
if(--ptr->use == 0) //comment1
-
delete ptr;
-
ptr = rhs.ptr;
-
val = rhs.val;
-
}
-
~HasPtr()
-
{
-
if(--ptr->use == 0)
-
delete ptr;
-
}
-
-
void set_ptr_val(int v)
-
{
-
*ptr->ip = v;
-
}
-
-
int get_ptr_val()
-
{
-
return *ptr->ip;
-
}
-
-
private:
-
U_Ptr *ptr;
-
int val;
-
};
方法很简单,但是如果c++基础知识了解的不清楚的话,有些地方还是有点疑惑的,比如说comment1,为什么先执行 ++rhs.ptr->use, 然后判断 --ptr->use==0, 我不知道你们是不是明白,但是至少我在刚看到这个地方的时候就搞不懂为什么!好,现在解释原因
1. 在c++中,如果对象在申明的同时马上进行初始化操作,则称之为拷贝运算
例如: HasPtr ptr1(p, val);
HasPtr ptr2(ptr1);
HasPtr ptr3 = ptr1; // 此时调用的是HasPtr(const HasPtr &orig),而非重载的赋值 操作符
2. 如果对象在申明之后再进行赋值操作,则称之为赋值运算
例如: HasPtr ptr1(p, val);
HasPtr ptr2(p2, val2);
ptr2 = ptr1; //这个时候调用的才是重载的赋值操作符,这个时候ptr2是另一个对 象,所以他需要先检查自己对应的对象是否需要删除!
阅读(4429) | 评论(0) | 转发(0) |