目录
1.RAll:
使用局部对象来管理资源的技术称为资源获取即初始化;这里的资源主要是指操作系统中有限的东西如内存,网络套接字,网络套接字,互斥量,文件句柄等等,局部对象是指存储在栈的对象,它的生命周期是由操作系统来管理的,无需人工介入。
1.1原理:
资源的使用一般经历三个步骤:
- 获取资源(创建对象)
- 使用资源
- 销毁资源(析构对象)
但是资源的销毁往往是程序员经常忘记的一个环节,所以程序界就想如何在程序员中让资源自动销毁呢?解决问题的方案是:RAlI,它充分的利用了C++语言局部对象自动销毁的特性来控制资源的生命周期。
1.2为什么使用智能指针,不使用裸指针:
裸指针不能确定指向是一个对象还是一组对象。
认识一下各种指针:
#include<iostream>
using namespace std;
class Object
{
int value;
public:
Object(int x = 0) :value(x) { cout << "Create Object" << endl; }
~Object() { cout << "Destory Object"; }
void Value()
{
cout << value;
}
};
void Destory(Object* op)
{
delete op;
}
int main()
{
Object*
int* ip;//野指针
Object* op = NULL;//空指针
op = new Object(10);
op->Value();
Destory(op);
//悬空指针
return 0;
}
2.c++17已经移除的auto_ptr:
c++11中已经弃用。
简单实现:
#include<iostream>
using namespace std;
class Object
{
int value;
public:
Object(int x = 0) :value(x) { cout << "Create Object" << this<<endl; }
~Object() { cout << "Destory Object"<<this<<endl; }
int& Value()
{
return value;
}
const int& Value()const { return value; };
};
template<class _Ty>
class my_auto_ptr
{
private:
bool Owns;//拥有权
_Ty* _Ptr;
public:
my_auto_ptr(_Ty* p = NULL) :Owns(p != NULL), _Ptr(p) {}
~my_auto_ptr()
{
if (Owns)
{
delete _Ptr;
Owns = false;
}
_Ptr = NULL;
}
_Ty* get()const { return _Ptr; };
_Ty& operator*()const
{
return *(get());
}
_Ty* operator->()const
{
return get();
}
};
void fun()
{
my_auto_ptr<Object>obj(new Object(10));
cout << sizeof(obj)<<endl;
cout << obj->Value() << endl;
cout << (*obj).Value() << endl;
}
int main()
{
fun();
return 0;
}
2.1智能指针的内存分布:
my_auto_ptr<Object>obj(new Object(10));
2.2如何解决->和*来调用成员方法(运算符重载)
_Ty* get()const { return _Ptr; };
_Ty& operator*()const
{
return *(get());
}
_Ty* operator->()const
{
return get();
}
get()返回_Ptr指针。重载*,表示对_Ptr的解引用,即Object对象本身。重载->,表示直接返回_Ptr。
2.3reset()函数:
指向另一个对象。
void reset(_Ty*p=NULL)
{
if (Owns)
{
delete(_Ptr);
}
_Ptr = p;
}
int main()
{
//fun();
my_auto_ptr<Object>obj(new Object(10));
obj.reset(new Object(100));
return 0;
}
2.4auto_ptr的缺点:
意义不明确:不能确定所有权到底如何划分。
my_auto_ptr<Object>obaj(new Object(10));
my_auto_ptr<Object>obbj(new Object(200));
//所有权不明确
my_auto_ptr<Object>obcj(obaj);
obbj = obaj;
STL中容器库都不带auto_ptr玩。