- 智能指针:管理资源,自动去释放资源
- RAII
RAII是一种利用对象生命周期来控制程序资源(如内存、文件局柄、网络连接,互斥量)的简单技术。
在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。我们实际是把管理一份资源的责任托管给了一个对象。这样做有两大好处:
1)不需要显示的释放资源
2)采用这种方式,对象所需的资源在其生命期内始终保持有效。
//RAII:管理指针
class A
{
public:
A(int n)
:_ptr(new int[n])
{}
~A()
{
if (_ptr)
{
delete[] _ptr;
}
}
protected:
int* _ptr;
};
void TestFunc()
{
int *p = new int;
A a(1);
}
int main()
{
TestFunc();
return 0;
}
- 智能指针的原理
上述代码它还不具有指针的行为。指针可以解引用,也可以通过->去访问所指向空间的内容,因此 在类中还需要将 ‘*’、‘->’重载下,才可让其像指针一样去使用。
智能指针的原理:
1、RAII特性
2、重载operator*()和operator->(),具有像指针一样的行为
/让一个类管理原生态指针
//RAII
//优势:用户不需要关心何时去释放资源
//缺陷:浅拷贝---不能采用深拷贝的方式解决
//String:资源是类自己申请的
//Smartptr可以管理资源,资源由用户申请
template<class T>
class Smartptr
{
public:
Smartptr(T* ptr)
:_ptr(ptr)
{
cout << "Smartptr()" << endl;
}
~Smartptr()
{
cout << "~Smartptr()" << endl;
if (_ptr)
{
delete _ptr;
}
}
//让该类的对象具有指针类似的行为
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
protected:
T* _ptr;
};
struct A
{
int a;
int b;
int c;
};
void TestFunc1()
{
Smartptr<int> sp1(new int);
*sp1 = 100;
Smartptr<A> sp2(new A);
sp2->a = 10;
sp2->b = 20;
sp2->c = 30;
}
//会出现浅拷贝的问题
void TestFunc2()
{
Smartptr<int> sp1(new int);
Smartptr<int> sp2(sp1);
}
int main()
{
TestFunc2();
return 0;
}
注意:使用默认的拷贝构造和赋值运算符重载,会造成浅拷贝
【一】 auto_ptr
1、auto_ptr原理:RAII+类对象具有类似指针的行为(operator*()/operator->())+解决浅拷贝
2、实现原理:资源转移。
3、缺陷:多个指针不能同时访问一份资源
//智能指针---Smartptr中遇到的浅拷贝问题
//智能指针原理:RAII+类对象具有类似指针的行为(operator*()/operator->())+解决浅拷贝
//C++98版本---auto_ptr:解决浅拷贝方式--->资源的转移
namespace bite
{
template<class T>
class auto_ptr
{
public:
//RAII
auto_ptr(T* ptr)
:_ptr(ptr)
{}
//ap2(ap1);
auto_ptr(auto_ptr<T>& ap)
:_ptr(ap._ptr)
{
ap._ptr = nullptr;
}
//ap1=ap2;
auto_ptr<T>& operator=(auto_ptr<T>& ap)
{
if (this != &ap)
{
if (_ptr)
{
delete _ptr;
}
_ptr = ap._ptr;
ap._ptr = nullptr;
}
return *this;
}
~auto_ptr()
{
if (_ptr)
{
delete _ptr;
}
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
protected:
T* _ptr;
};
}
void TestFunc()
{
//常规指针
int a = 10;
int* p1 = &a;
int* p2(p1);
*p1 = 100;
*p2 = 200;
bite::auto_ptr<int> ap1(new int);
//解决方式:将资源转移
bite::auto_ptr<int> ap2(ap1);
//*