RAII
(
Resource Acquisition Is Initialization
)是一种
利用对象生命周期来控制程序资源
(如内存、文件句柄、网络连接、互斥量等等)的简单技术。
在对象构造时获取资源
,接着控制对资源的访问使之在对象的生命周期内始终保持有效,
最后在对象析构的
时候释放资源
。借此,我们实际上把管理一份资源的责任托管给了一个对象。这种做法有两大处:
不需要显式地释放资源。
采用这种方式,对象所需的资源在其生命期内始终保持有效。
#include<iostream>
#include<memory>
#include<vld.h>
//auto_ptr 自动指针 VC
//auto_ptr Linux vs
//boost scoped_ptr scoped_array shared_array weak_ptr instrusive_ptr
//C11 unique_ptr shared_ptr
using namespace std;
void test01()
{
int* ptr = new int(10);
auto_ptr<int> pa(ptr);//智能指针
//delete ptr;
cout << *pa << endl;
string* pstr = new string("abcxyz");
auto_ptr<string> ps(pstr);
cout << ps->size() << endl;
cout << "end." << endl;
}
//boost
//寻找第三方代理
//智能 指针
void main()
{
test01();
//system("pause");
}
指针可以解引用,也可以通过
->
去访问所指空间中的内容,因此:
AutoPtr
模板类中还得需要将
*
、
->
重载下,才可让其像指针一样去使用
。
总结一下智能指针的原理:
1. RAII
特性
2.
重载
operator*
和
opertaor->
,具有像指针一样的行为。
auto_ptr在VC6的底层实现
#include<iostream>
#include<vld.h>
using namespace std;
namespace hym
{
template<class _Ty>
class auto_ptr
{
public:
auto_ptr(_Ty* _P = 0) : _Ptr(_P), _Owns(_P != 0)
{}
//auto_ptr(auto_ptr<_Ty>& _Y)
//{
// this->_Ptr = _Y._Ptr;
// this->_Owns = _Y._Owns;
// _Y._Owns = false;
//}
auto_ptr(const auto_ptr<_Ty>& _Y) :_Owns(_Y._Owns), _Ptr(_Y.release())
{}
auto_ptr<_Ty>& operator=(const auto_ptr<_Ty>& _Y)
{
if (this != &_Y)
{
if (_Ptr != _Y.get())
{
if (_Owns)
delete _Ptr;
_Owns = _Y._Owns;
}
else if (_Y._Owns)
_Owns = true;
_Ptr = _Y.release();
}
return (*this);
}
~auto_ptr()
{
if (_Owns)
delete _Ptr;
}
//_Ty* release(const auto_ptr* const this)
//_Ty* release()const
//{
// ((auto_ptr<_Ty>*)this)->_Owns = false;
// return _Ptr;
//}
//_Ty* get() const
//{
// return (_Ptr);
//}
//_Ty& operator*()
//{
// return (*get()); //*_Ptr
//}
//_Ty* operator->()
//{
// return _Ptr;
//}
private:
bool _Owns; //拥有权 true false
_Ty* _Ptr; //管理空间
};
};
class Test
{
public:
Test(int a = 0) :m_a(a) {}
void fun()
{cout << "m_a=" << m_a << endl;}
private:
int m_a;
};
void test01()
{
int* ptr = new int(10);
auto_ptr<int> pa(ptr);
auto_ptr<int> pb;
cout << *pb << endl;
}
void test02()
{
int* ptr = new int(10);
int* ptr1 = new int(10);
hym::auto_ptr<int> pa=ptr;
hym::auto_ptr<int> pa1=ptr1;//微妙 而断丝连
hym::auto_ptr<int> pa2 = pa1;
pa1 = pa;
*pa = 100;
cout << *pa << endl;
cout << *pa1 << endl;//vc6版本的拷贝构造之后原来的对象仍然可以使用
}
void test03()
{
Test* pt = new Test(50);
hym::auto_ptr<Test> pa(pt);
pa->fun();
}
void test04()
{
int* ptr = new int(10);
auto_ptr<int> pa(ptr);
auto_ptr<int> pa1 = pa;
cout << *pa1 << endl;
//cout << *pa << endl;//VS版本拷贝构造后原来的对象无法使用
}
void main()
{
test04();
}
auto_ptr在VS的底层实现:
#include<iostream>
#include<vld.h>
using namespace std;
namespace hym
{
template<class _Ty>
class auto_ptr
{
typedef auto_ptr<_Ty> _Myt;
public:
explicit auto_ptr(_Ty* Ptr = 0) :_Myptr(Ptr) {}
auto_ptr(_Myt& _Right) :_Myptr(_Right.release()) {}
_Myt& operator=(_Myt& _Right)
{
reset(_Right.release());
return *this;
}
_Ty* get() const
{
return (_Myptr);
}
_Ty& operator*()
{
return (*get()); //*_Ptr
}
_Ty* operator->()
{
return _Myptr;
}
~auto_ptr()
{
delete _Myptr;
}
_Ty* release()
{
_Ty* _Tmp = _Myptr;
_Myptr = nullptr;
return _Tmp;
}
void reset(_Ty* _Ptr = 0)
{
if (_Ptr != _Myptr)
delete _Myptr;
_Myptr = _Ptr;
}
private:
_Ty* _Myptr;
};
}
void test01()
{
int* ptr = new int(10);
hym::auto_ptr<int> pa(ptr);
//hym::auto_ptr<int> pa1 = pa;
//cout << *pa << endl;
cout << *pa<< endl;
int* q = new int(100);
pa.reset(q);
pa.reset(q);
//pa.reset(nullptr);
//pa.release();
int* tmp = pa.release();
delete tmp;
}
void test02()
{
int* ptr = new int(10);
int* ptr1 = new int(50);
auto_ptr<int> pa(ptr);
auto_ptr<int> pa1(ptr1);
pa1 = pa;
cout << "*pa1="<<*pa1 << endl;
//cout << "*pa=" << *pa << endl;
}
void main()
{
test02();
//system("pause");
}
boost库的scoped_ptr:所有权不能发生转移。
#include<iostream>
#include<vld.h>
#include<boost/smart_ptr.hpp>
using namespace std;
using namespace boost;
class Test
{
public:
void fun()
{
cout << "Test.fun()" << endl;
}
};
void test01()
{
int* ptr = new int(10);
scoped_ptr<int> ps(ptr);
cout << *ps << endl;
Test* pt1 = new Test;
scoped_ptr<Test> ps2(pt1);
ps2->fun();
}
void test02()
{
int* ptr = new int(10);
scoped_ptr<int> ps(ptr);
//scoped_ptr<int> ps1 = ps;//拥有权不能转移
scoped_ptr<int> ps2;
//ps2 = ps1;//所有权不能转移
}
void test03()
{
int* ptr = new int(10);
auto_ptr<int> pa(ptr);
scoped_ptr<int> ps(pa);
}
void main()
{
test03();
}