智能指针(smart pointer)是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动态分配的对象,防止悬垂指针的出现。在类对象中,如果定
义一个int型的指针,当多次使用同一个已存在的对象初始化一些新建对象时,已存在的对象和新建的对象都指向同一块内存区域,当我们在使用某一个对象时释放了该内存空间,
那么其它对象的int型指针域全都会失效,为了防止这种情况的产生,我们通常定义一个类,这个类里有一个引用计数器(用来统计有多少个对象指向共享内存区域)和一个int型的指
那么这块共享区域就由该智能指针类管理,下面是一张来自c++ primer的结构图:
简单实现:
/*
智能指针类设计实现
*/
#include<iostream>
#include<vector>
#include<map>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<list>
#include<cstring>
using namespace std;
class smartpointer{//定义一个智能指针类
private:
friend class own;
int *p;//被管理内存的类型
size_t use;//对象使用计数器
smartpointer(int *pt) :use(1), p(pt){}
~smartpointer(){ delete p; }
};
typedef struct t{
smartpointer *spt;
struct t *next;
}node;
class own{
public:
//复制控制部分
own(int *p,int val){
int flag = true;
if (link == NULL){//如果是空的话
node *temp = new node;
temp->spt = new smartpointer(p);
temp->next = NULL;
link= temp;
}
else{
node *head = link;
while (head != NULL){
if (p ==head->spt->p){
ptr = head->spt;
ptr->use++;
value = val;
flag = false;
break;
}
head=head->next;
}
}
if (true){
node *temp=new node;
ptr = new smartpointer(p);
temp->spt = ptr;
temp->next = link;
link = temp;
value = val;
}
}
own & operator=(const own &obj){
++obj.ptr->use;
if (--ptr->use == 0)delete ptr;
value = obj.value;
ptr = obj.ptr;
return *this;
}
own(const own&obj){
value = obj.value;
ptr = obj.ptr;
ptr->use++;//两者指向同一个智能指针对象
}
~own(){
if (ptr->use == 0)delete ptr;
}
//获取类的值
int *get_ptr(){
return ptr->p;
}
int get_value(){
return value;
}
void set_ptr(int *new_ptr){//将其设置为指向一个新值的
ptr->use--;
if (ptr->use == 0)delete ptr;
ptr = new smartpointer(new_ptr);
}
void set_val(int val){
value = val;
}
private:
int value;
smartpointer *ptr;
static node *link ;//用来保存已经存在的smartpoint类对象
};
node *own::link = NULL;//刚开始设为空值
int main(){
int *p = new int[50];
own b1(p, 1);
own b2(p, 2);
cout << b1.get_ptr() << endl;
cout << b2.get_ptr() << endl;
delete []p;
return 0;
}
/*
以上智能指针的实现做了如下优化:
1.当用同一块内存去建立own对象时,不会新建smartpointer类
*/
其中我们用link变量将own类所有对象所指的内存区域链接起来,当用一个内存块新建一个own对象时,我们先检查p是否是已经新建的内存块,如果是的,我们就将对象的
ptr域指向已有的smartpoint类对象,如果p不存在,我们这个时候才新建一个smartpoint类对象.