智能指针:就是智能/自动化的管理指针所指向的动态资源的释放.
auto_ptr:是C++标准库中为了解决资源泄漏的问题提供的一个智能指针类模板。
使用auto_ptr 要注意:不要让两个auto_ptr指向同一个对象,auto_ptr不能指向数组,一个对象只能由一个auto_ptr所拥有,
在给其他auto_ptr赋值时,会转移这种拥有关系。
scoped_ptr:scoped_ptr是boost库里的智能指针,scoped_ptr不能拷贝,不能用于管理数组对象
shard_ptr :采用了引用计数的方法可以有多个shard_ptr 对同一个对象进行管理
模拟实现 auto_ptr
<span style="font-size:18px;">#pragma once
#include<iostream>
using namespace std;
template <typename T>
class AutoPtr
{
friend ostream& operator<<(ostream& os, AutoPtr<T> op)
{
os << *(op.m_ptr) << endl;
return os;
}
public:
AutoPtr(T*ptr = 0) :m_ptr(ptr)
{}
AutoPtr(AutoPtr<T>& p) :m_ptr(p.m_ptr)
{
p.m_ptr = NULL;
}
AutoPtr& operator = (AutoPtr<T>& op)
{
if (op.m_ptr != m_ptr)
{
delete m_ptr;
m_ptr = op.m_ptr;
op.m_ptr = NULL;
}
return *this;
}
T& operator *()
{
return *m_ptr;
}
T* operator->()
{
return m_ptr;
}
~AutoPtr()
{
if (m_ptr != NULL)
{
delete m_ptr;
}
m_ptr = NULL;
}
T* release()
{
return m_ptr;
}
void reset(T* ptr)
{
m_ptr = ptr;
}
private:
T* m_ptr;
};
</span><pre name="code" class="cpp">void TestAutoptr()
{
AutoPtr<int> p;
p.reset(new int);
*p = 10;
cout << *p << endl;
int* ptr = p.release();
cout << "ptr =" << *ptr << endl;
AutoPtr<int> ap1(new int(1));
AutoPtr<int >ap2(ap1);
AutoPtr<int>ap3(new int(3));
ap3 = ap2;
cout << ap3 << endl;
}
int main()
{
TestAutoptr();
system("pause");
return 0;
}
模拟实现scoped_ptr
<span style="font-size:18px;">#pragma once
#include<iostream>
using namespace std;
template<typename T>
class ScopedPtr
{
public:
ScopedPtr(T*ptr = 0) :m_ptr(ptr)
{}
~ScopedPtr()
{
if (m_ptr != NULL)
{
delete m_ptr;
m_ptr = NULL;
}
}
T&operator*() //注意返回引用
{
return *m_ptr;
}
T* operator->()
{
return m_ptr;
}
T*Get()
{
return m_ptr;
}
private:
ScopedPtr( const ScopedPtr<T>& op);//不允许该智能指针,拷贝构造
ScopedPtr& operator =(ScopedPtr<T>& op);//不允许赋值
private:
T*m_ptr;
};</span>
<span style="font-size:18px;">void TestScopedptr()
{
ScopedPtr<int> p1(new int(3));
cout << *p1 << endl;
ScopedPtr<B> p2(new B);
p2->b = 5;
cout << p2->b<<endl;
}</span>
<pre name="code" class="cpp"><span style="font-size:18px;">int main()
{
TestScopedptr();
system("pause");
return 0;
}</span>
模拟实现shard_ptr
<span style="font-size:18px;">#pragma once
#include <iostream>
using namespace std;
template<typename T>
class ShardPtr
{
public:
ShardPtr(T* ptr = 0) :m_ptr(ptr),m_pCount(new int(1)){}
ShardPtr(const ShardPtr<T>& shp)
{
m_ptr = shp.m_ptr;
m_pCount = shp.m_pCount;
++Getcount();
}
~ShardPtr()
{
Release();
}
ShardPtr& operator = (const ShardPtr<T>&shp)
{
if (m_ptr != shp.m_ptr)
{
Release();
m_ptr = shp.m_ptr;
m_pCount = shp.m_pCount;
++Getcount();
}
return *this;
}
T* operator->()
{
return m_ptr;
}
T& operator*()
{
return *m_ptr;
}
T* Get()
{
return m_ptr;
}
private:
void Release()
{
if (--Getcount() == 0)
{
delete m_ptr;
m_ptr = NULL;
delete m_pCount;
m_pCount = NULL;
}
}
int& Getcount()//引用计数
{
return *m_pCount;
}
private:
T* m_ptr;
int* m_pCount;//指向引用计数的指针
};</span>
<span style="font-size:18px;"></span><pre name="code" class="cpp" style="color: rgb(51, 51, 51); line-height: 25.2px;"><span style="font-size:18px;"></span><pre name="code" class="cpp">oid TestShardPtr()
{
class A
{
public:
A(int a = 0) :m_a(a)
{
cout << "A()" << endl;
}
void display()
{
cout << "hello" << endl;
}
private:
int m_a;
};
ShardPtr<int>p1(new int(2));
ShardPtr<int> p2(p1);
ShardPtr<A> p3(new A);
p3->display();
ShardPtr<A>p4;
p4 = p3;
(*p4).display();
}
return *m_pCount;}
<span style="font-size:18px;">int main()
{
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>TestShardPtr();
<span style="white-space:pre"> </span>system("pause");
<span style="white-space:pre"> </span>return 0;
}
</span>