说明:
在使用c++语言编程时、为了防止忘记对申请的空间进行释放、我们通常使用智能指针来管理对象。智能指针有很多种、它们适用于不同的场合。
auto_ptr:只允许唯一的一个auto_ptr对象管理一个资源、在拷贝时会自动将原auto_ptr指向置空。
unique_ptr:同一时刻只允许一个unique_ptr对象指向指定资源、不允许拷贝、通过release()释放所有权、move移动所有权。
shared_ptr:使用引用计数的智能指针、当内部引用计数为0时将释放资源。
weak_ptr:配合shared_ptr使用的智能指针、它不会共享资源、也不会使引用计数变化、使用它是为了解决由于循环引用而导致shared_ptr包装的资源无法被释放的问题、可通过lock方法获得一个可用的shared_ptr对象。
下面是我写的一个简单的计数型智能指针:
#ifndef _SMART_PTR_H
#define _SMART_PTR_H
#include<iostream>
#include<string>
#include<memory>
using namespace std;
template<class T>
class smart_ptr
{
private:
T* ptr;
int* count;
public:
explicit smart_ptr(T* p = 0):ptr(p),count(new int)
{
if(ptr)
*count = 1;
else
*count = 0;
}
smart_ptr(const smart_ptr& sp)
{
if(this != &sp){
this->ptr = sp.ptr;
this->count = sp.count;
if(this->ptr) //要判断当前是否指向了资源
++*count;
}
}
~smart_ptr()
{
if(this->ptr)
{
--*count;
if(*count == 0){
delete ptr;
delete count;
ptr = NULL;
count = NULL;
}
}
}
public:
smart_ptr& operator=(const smart_ptr& sp)
{
if(this->ptr == sp.ptr)
return *this;
if(this->ptr)
{
--*count;
if(*count == 0){
delete ptr;
delete count;
ptr = NULL;
count = NULL;
}
}
this->ptr = sp.ptr;
this->count = sp.count;
if(this->ptr)
++*count;
return *this;
}
T& operator*()
{
if(this->ptr)
return *this->ptr;
throw string("Invalid pointer");
}
T* operator->()
{
if(this->ptr)
return this->ptr;
throw string("Invalid pointer");
}
public:
int use_count()
{
return *count;
}
bool unique()
{
return this->use_count() == 1;
}
void swap(smart_ptr<T>& sp)
{
std::swap(*this,sp);
}
void reset(T* p = 0)
{
if(ptr){
--*count;
if(*count == 0){
delete ptr;
delete count;
ptr = NULL;
count = NULL;
}
}
ptr = p;
count = new int;
if(this->ptr){
*count = 1;
}else
*count = 0;
}
T* get()
{
return ptr;
}
};
#endif
测试一下:
#include <iostream>
#include <string>
using namespace std;
#include "smart_ptr.h"
int main()
{
try{
smart_ptr<string> sp(new string("123"));
smart_ptr<string> sp2;
smart_ptr<string> sp3;
sp3 = sp;
sp2.reset(new string("aaas"));
cout<<*sp<<endl;
cout<<*sp2<<endl;
sp.swap(sp2);
cout<<*sp<<endl;
cout<<*sp2<<endl;
cout<<*sp3<<endl;
cout<<sp.use_count()<<endl;
cout<<sp2.use_count()<<endl;
cout<<sp.get()->substr(1)<<endl;
}catch(string& e)
{
cout<<e<<endl;
}
system("pause");
return 0;
}
运行结果: