1 带 pointer mem 的 简单 class
1. default copy ctor / assignment
, 都 只 copy pointer, 不 copy target object
`(1) synthesized copy ctor`
int obj = 0;
// ctor
HasPtr hp1(&obj, 0);
//默认复制
HasPtr hp2(hp1);
(2) synthesized assigment operator
int obj1 = 0;
HasPtr hp1(&obj1, 1);
int obj2 = 2;
HasPtr hp2(&obj, 3);
// synthesized assigment
HasPtr hp2 = hp1;
2. share
target obj + 悬垂指针:
多个 HasPtr
obj ( 的 internal ptr ) share
the same pointed object
时, 1 个 delete the target obj
-> 另一个 无法感知 target obj 是否存在
-> 若已 被 delete -> 悬垂指针
=>
`由 HasPtr 的 client 保证 target obj 存在`
=>
`无法避免 悬垂指针`
int* p = new int(1);
HasPtr hp(p, 2);
delete p;
hp.set_ptr_val(0);
=>
p 与 hp.ptr 指向同一 obj,
若 用 p delete this obj -> hp.ptr 指向 invalid 内存
// 5. implement of SP
#include <iostream>
template <class T>
class HasPtr
{
private:
T* pt;
int val;
public:
HasPtr(T* pt1, int i) : pt(pt1), val(i) { }
~HasPtr()
{
//若 hp1 hp2 的 pointer mem 指向同一 obj,
//hp1 hp2 两者 后消亡者 call this dtor 时, 指针悬挂
delete pt;
}
// common function
T* get_ptr() const { return pt; }
int get_val() const { return val; }
void set_ptr(T* p) { pt = p; }
void set_val(int i) { val = i; }
T get_ptr_val() const { return *pt; }
void set_ptr_val(T t) { *pt = t; }
};
int main()
{
int* p1 = new int(5);
int* p2 = new int(10);
HasPtr<int> hp1 = HasPtr<int>(p1, 1);
HasPtr<int> hp2 = HasPtr<int>(p2, 2);
hp2 = hp1;
}
2 智能指针 / Smart Pointer ( SP ) class
本节 所讲 只是 shared_ptr
internal ptr 所指 object shared
+ class avoid 悬垂指针
1. 引用计数 ( reference count / RC )
用1个 counter
跟踪 SP class 有几个
object share
the same ptr
( to target object
)
仅当 SP object 感知到自己 ( 的 internal ptr )
is the last ptr ( 靠 RC ) to target object
时, dtor 中才 delete internal ptr
=> 调 the pointed/target object 的 dtor
-> 再 free memory of pointer mem itself
`2. 限制`
target obj
(1) 由 client dynamically allocate
-> address 传给 class HasPtr
(2) 不能被 non-SP 的 external ptr delete
(3) delete
by the last HasPtr obj's internal ptr: 由 SP 保证
3. `SP 实现`
(1) ctor
1) init. internal ptr
2) counter = 1
(2) copy ctor
1) copy ptr
2) ++counter
(3) assignment operator
1) 左 --counter,
若减为 0 -> delete ptr
2) 右 ++counter
(4) dtor
--counter
若减为 0 -> delete ptr
4. RC 放哪 ?
(1) 不能放 SP object 中
reason: 无法保证 all SP obj 中, RC 值 都正确
// eg.
copy ctor:
1) old obj's RC++
2) new obj's RC update 为 old obj's RC
=>
1 个 SP obj 2次 copy:
原 obj 与 第 2 copy 的 RC 都 = 3,
但 第 1 copy 的 RC =
=> error
template <class T>
class HasPtr
{
private:
T* pt;
int val;
size_t RC;
};
int obj;
HasPtr<int> hp(&obj, 10);
HasPtr<int> hp1(hp);
HasPtr<int> hp2(hp);
`(2) reference count 一种正确放置 的 策略`
用 1 个 class U_Ptr 封装 RC 与 internal ptr
U_Ptr 所有成员 private
1) 阻止 ordinary client use
2) SP 设为 U_Ptr 的 friend, 以使 SP's mem 可 access U_Ptr's mem
#include <iostream>
// forward declaration
template <class T>
class SP;
template <class T>
class U_Ptr
{
// 1) SP as friend
friend class SP<T>;
private:
// 2) ptr + RC
T* pt;
size_t RC;
// 3) single para ctor: RC init 1
U_Ptr(T* _pt)
: pt(_pt), RC(1) { }
// 4) dtor
// SP dtor: delete pU -> call U_Ptr dtor: delete pt without check
~U_Ptr() { delete pt; }
};
template <class T>
class SP
{
private:
// note: class template internal / external:
// <T> must exist / needn't after class name
U_Ptr<T>* pU;
int val;
public:
//(1) ctor: pt passed by SP's client
SP(T* pt, int _val) :
pU( new U_Ptr<T>(pt) ), val(_val) { }
//(2) copy ctor: ++RC
SP(const SP& hp) :
pU(hp.pU), val(hp.val)
{
++pU->RC;
}
//(3) operator=
SP& operator=(const SP& rhs);
//(4) dtor
~SP()
{
if (--pU->RC == 0)
delete pU;
}
};
template <class T>
SP<T>&
SP<T>::operator=(const SP<T>& rhs)
{
// 1) right ++RC
++rhs.pU->RC;
// 2) left --RC
if (--pU->RC == 0)
delete pU;
// 3) pU 赋值
pU = rhs.pU;
val = rhs.val;
// 4)
return *this;
}
int main()
{
int* p1 = new int(5);
int* p2 = new int(10);
SP<int> hp = SP<int>(p1, 1);
SP<int> rhp = SP<int>(p2, 2);
hp = rhp;
}
3 值型 class
ctor / copy ctor: 以 T 型 arg 为 初值 -> new -> 被 internal ptr 指向
pointer mem 所指 object unique / 独立管理
// eg1.
#include <iostream>
template <class T>
class HasPtr
{
private:
T* pt;
int val;
public:
// ctor
HasPtr(const T& _t, int i) :
pt( new T(_t) ),
val(i)
{ }
// copy ctor
//1) no longer copy pointer
//2) allocate a new object
//3) initialize new obj's value
// equal to the copied obj's value
HasPtr(const HasPtr& rhs) :
pt( new T(*rhs.pt) ),
val(rhs.val)
{ }
HasPtr& operator=(const HasPtr& rhs);
~HasPtr()
{
delete pt;
}
};
template <class T>
HasPtr<T>&
HasPtr<T>::operator=(const HasPtr<T>& rhs)
{
//1) operator= 不需要 allocate new obj
//2) 左右 操作数 相同时, 赋值也安全
// => `不用 check 自身赋值`
*pt = *rhs.pt;
val = rhs.val;
return *this;
}
int main()
{
int a = 5;
int b = 10;
// 先 new 再调用 ctor 时, ctor 改成和 普通类中 相同
HasPtr<int> hp1 = HasPtr<int>(a, 1);
HasPtr<int> hp2 = HasPtr<int>(b, 2);
hp2 = hp1;
}
// eg2. equivalent to eg1
template <class T>
class HasPtr
{
//...
public:
// ctor
HasPtr(T* pt1, int i) :
pt(pt1), val(i) { }
};
int main()
{
int* p1 = new int(5);
int* p2 = new int(10);
HasPtr<int> hp1 = HasPtr<int>(p1, 1);
HasPtr<int> hp2 = HasPtr<int>(p2, 2);
hp2 = hp1;
}