智能指针(上)
#define_CRT_SECURE_NO_WARNINGS1
//AutoPtr(新方案)
#include
usingnamespacestd;
template <classT>
classAutoPtr
{
public:
AutoPtr(T* ptr)
:_ptr(ptr)
{}
AutoPtr(AutoPtr<T>&ap)
:_ptr(ap._ptr)
{
ap._ptr= NULL; //交换管理权,将ap1置空
}
AutoPtr <T>&operator=(AutoPtr<T>&ap)
{
if(this != &ap) //防止自赋值
{
delete_ptr; //删除空间(不让指针指向自己的空间)
_ptr= ap._ptr; //管理权转移(相当于ap3指向了ap2)
ap._ptr= NULL; //置空(ap2)
}
return*this;
}
T& operator*()
{
return*_ptr;
}
T* operator->()
{
return_ptr;
}
~AutoPtr()
{
if(_ptr)
{
cout<< "delete:"<< _ptr << endl;
delete_ptr;
_ptr= NULL;
}
}
protected:
T* _ptr;
};
structA
{
int_a;
};
int main()
{
AutoPtr<int>ap1(newint(1));
AutoPtr<int>ap2(ap1);
AutoPtr<int>ap3(newint(2));
ap3 =ap2;
*ap3 =1;
AutoPtr<A>ap4(newA);
ap4->_a= 6;
return0;
}
//ScopedPtr:守卫指针
#include
usingnamespacestd;
template<classT>
classScopedPtr
{
public:
ScopedPtr(T* ptr)
:_ptr(ptr)
{}
~ScopedPtr()
{
if(_ptr)
{
cout<< "delete:"<< _ptr << endl;
delete_ptr;
}
}
T& operator*()
{
return*_ptr;
}
T* operator->()
{
return_ptr;
}
protected: //防拷贝,防止函数被在类外实现
ScopedPtr(ScopedPtr<T>&sp); //只声明不实现
ScopedPtr<T>&operator=(ScopedPtr<T>&sp);
protected:
T* _ptr;
};
structA
{
int_a;
};
int main()
{
ScopedPtr<int>sp1(newint(1));
//ScopedPtr
*sp1 =1;
ScopedPtr<A>sp2(newA);
sp2->_a= 5;
return0;
}
//SharedPtr(共享指针)
#include
usingnamespacestd;
template<classT>
classSharedPtr
{
public:
SharedPtr(T* ptr)
:_ptr(ptr)
,_pcount(newint(1))
{}
~SharedPtr()
{
if(--(*_pcount) == 0)
{
delete_ptr;
delete_pcount;
}
}
SharedPtr(constSharedPtr<T>&sp)
:_ptr(sp._ptr)
,_pcount(sp._pcount) //两个指针指向同一块空间
{
++(*_pcount); //计数加1
}
SharedPtr<T>&operator=(constSharedPtr<T>& sp)
{
if(_ptr != sp._ptr) //(1)防止自赋值;(2)两个指针管理同一块空间
{
if(--(*_pcount) == 0) //(3)两个指针分别指向两块空间时
{
delete_ptr;
delete_pcount;
}
_ptr= sp._ptr;
_pcount= sp._pcount;
++(*_pcount);
}
return*this;
}
T& operator*()
{
return*_ptr;
}
T* operator->()
{
return_ptr;
}
protected:
T* _ptr;
int*_pcount; //计数指针
};
structA
{
int_a;
};
int main()
{
SharedPtr<int>sp1(newint(1));
SharedPtr<int>sp2(sp1);
SharedPtr<int>sp3(sp2);
SharedPtr<int>sp4(newint(2));
sp1 =sp4;
*sp4 =6;
SharedPtr<A>sp5(newA);
sp5->_a= 5;
return0;
}
智能指针(下)
//1.AutoPtr的另一种写法。(旧方案)
#include
usingnamespacestd;
template<classT>
classAutoPtr
{
public:
AutoPtr(T* ptr)
:_ptr(ptr)
,_owner(true)
{}
~AutoPtr()
{
if(_owner) //只要_owner为真,则析构
{
delete_ptr;
}
}
AutoPtr(AutoPtr<T>&ap)
:_ptr(ap._ptr)
{
ap._owner= false;
}
AutoPtr<T>&operator=(AutoPtr<T>&ap)
{
if(this != &ap)
{
_ptr= ap._ptr;
ap._owner= false;
}
return*this;
}
T& operator*()
{
return*_ptr;
}
T* operator->()
{
return_ptr;
}
protected:
T* _ptr;
bool_owner;
};
structA
{
int_a;
};
int main()
{
AutoPtr<int>ap1(newint(1));
AutoPtr<int>ap2(ap1);
AutoPtr<int>ap3(newint(2));
ap3 =ap2;
*ap3 =10;
AutoPtr<A>ap4(newA);
ap4->_a= 20;
return0;
}
//AutoPtr虽然存在问题,但是不能废除,因为存在兼容性问题,要保证之前的代码还可以兼容。尽量不要使用就好。
//Question:新方案和旧方案哪个更好?
//答:新方案较好。(1)旧方案占的内存大于新方案;(2)旧方案的每个指针变量的值都可以修改,不安全;(3)当出现
//以下情况时新方案优于旧方案
//AutoPtr
//if (xxx)
//{
// AutoPtr
//}
//用ap1拷贝构造出ap2时,ap1的_owner为false,ap2的_owner为true;但是当ap2出了作用域后会发生析构,此时若使用*ap1*的
//的方式修改ap1的值时,会出现野指针(垂悬指针)的问题,导致程序出现错误。
//定置删除器
#include
#include
usingnamespacestd;
struct Free
{
voidoperator()(void* ptr)
{
cout<< "Free" << ptr<< endl;
free(ptr);
}
};
void TestSharedPtr()
{
int*p1 = (int*)malloc(sizeof(int)*10);
shared_ptr<int>sp(p1, Free());
/*FILE*p2 = fopen("test.txt", "r");
shared_ptr
}
//仿函数(类,重载了operator[],不是函数像函数)
template<classT>
structLess
{
booloperator()(constT&l,constT& r)
{
returnl< r;
}
};
int main()
{
TestSharedPtr();
//Less
//cout<< less(1, 2) << endl;
return0;
}
//2.模拟SharedPtr的定置删除器
#include
usingnamespacestd;
template<classT>
structDefaultDel //默认删除器
{
voidoperator()(T* ptr)
{
deleteptr;
}
};
template<classT,classD=DefaultDel<T>>
classSharedPtr
{
public:
SharedPtr(T* ptr)
:_ptr(ptr)
,_pcount(newint(1))
{}
SharedPtr(T* ptr,Ddel)
:_ptr(ptr)
,_pcount(newint(1))
,_del(del)
{}
~SharedPtr()
{
_Release();
}
SharedPtr(constSharedPtr<T,D>& sp)
:_ptr(sp._ptr)
,_pcount(sp._pcount) //两个指针指向同一块空间
{
++(*_pcount); //计数加1
}
SharedPtr<T, D>& operator=(constSharedPtr<T, D>& sp)
{
if(_ptr != sp._ptr) //(1)防止自赋值;(2)两个指针管理同一块空间//(3)两个指针分别指向两块空间时
{
_Release();
_ptr= sp._ptr;
_pcount= sp._pcount;
++(*_pcount);
}
return *this;
}
T& operator*()
{
return*_ptr;
}
T* operator->()
{
return_ptr;
}
T* GetPtr()
{
return_ptr;
}
protected:
void_Release()
{
if(--(*_pcount) == 0)
{
/*delete_ptr;*/
_del(_ptr);
delete_pcount;
}
}
protected:
T* _ptr;
int*_pcount; //计数指针
D _del;
};
template<classT>
structFree
{
voidoperator()(T* ptr)
{
free(ptr);
}
};
void TestDeleter()
{
SharedPtr<int, DefaultDel<int>>sp1(newint(1));
SharedPtr<int, Free<int>>sp2((int*)malloc(sizeof(int)));
SharedPtr<int>sp3(newint(1));
}
int main()
{
return0;
}
//3.学习定置删除器和循环引用的场景并理解
//循环引用
#include
#include
usingnamespacestd;
void Test()
{
shared_ptr<int>sp1(newint(1));
shared_ptr<int>sp2(sp1);
cout<< "sp1:"<< sp1.use_count()<< endl;
cout<< "sp2:"<< sp2.use_count()<< endl;
}
structNode
{
shared_ptr<Node>_next;
shared_ptr<Node>_prev;
~Node()
{
cout<< "delete:"<<this<< endl;
}
};
void TestSharedPtr()
{
shared_ptr<Node>cur(newNode());
shared_ptr<Node>next(newNode());
cur->_next= next;
next->_prev= cur; //析构时会相互等待(cur和next)
}
int main()
{
/*Test();*/
TestSharedPtr();
getchar();
return0;
}
//循环引用的解决
//weak_ptr打破了循环,不增加引用计数,也重载operator*/operator->
#include
#include
usingnamespacestd;
void Test()
{
shared_ptr<int>sp1(newint(1));
shared_ptr<int>sp2(sp1);
cout<< "sp1:" << sp1.use_count()<< endl;
cout<< "sp2:" << sp2.use_count()<< endl;
}
structNode
{
weak_ptr<Node>_next;
weak_ptr<Node>_prev;
~Node()
{
cout<< "delete:"<< this << endl;
}
};
void TestSharedPtr()
{
shared_ptr<Node>cur(newNode());
shared_ptr<Node>next(newNode());
cout<< "cur:" << cur.use_count()<< endl;
cout<< "next:"<< next.use_count() << endl;
cur->_next= next;
next->_prev= cur;
cout<< "赋值后:" << endl;
cout<< "cur:" << cur.use_count()<< endl;
cout<< "next:"<< next.use_count() << endl;
}
int main()
{
/*Test();*/
//TestSharedPtr();
shared_ptr<int> sp(newint(10));
weak_ptr<int>wp(sp);
getchar();
return0;
}