// ObjGC.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdlib.h> #include <memory> #define TRACE printf #define SAFEPTR_TRACE TRACE /* 安全指针(safe_ptr) 不知道叫什么好,就叫这个吧,刚好没跟别的命名冲突 简单的讲就是一个所有权委托的智能指针,与aoto_ptr有点类似,不过实现方式不太一样 优点: 在作为返回数据很是方便,只返回了一个指针而已,但是是必须有safe_ptr类型指针来接收 使用方式: safe_ptr<类型> 变量名(是否出事化空间) 如: safe_ptr<int> i(true); 定义了一个int指针,并在堆上开辟了空间 实现原理: 在一个结构体前面增加一个指针,这个指针标记的是谁在引用自己,如果要赋值给另外一个对象,将会把所有权移交出去,移交之后,自己就不能回收了,另一个safe_ptr将接管 不管什么时候,数据只指向一个拥有者,所有权移交一般在函数返回常用到,用来为上层函数提供大型数据 safe_st 将数据封装为带有所有着标记的结构体 safe_ptr 只有一个成员AuthT,是一个指向safe_st的指针, safe_st.author的值就是AuthT的地址,并不是safe_st的地址 有任何意见,希望联系本人,争取完美点 2010-11-11 杨小伟 QQ66091282 */ template<class T> struct safe_st { safe_st<T> ** author; T data; }; template<class T> struct safe_ptr { safe_st<T> *AuthT; safe_ptr(bool bNew=false) { AuthT=0; if (bNew) //初始化指针 { AuthT = new safe_st<T>(); AuthT->author=&AuthT; memset(&AuthT->data,NULL,sizeof(T)); SAFEPTR_TRACE("初始化 AuthT:%08X author:%08X, data:%d/n",&AuthT, AuthT->author,AuthT->data); } } ~safe_ptr() { if ( AuthT && (AuthT->author==&AuthT) ) { SAFEPTR_TRACE("析构 AuthT:%08X author:%08X, data:%d/n",&AuthT, AuthT->author,AuthT->data); delete AuthT; } } //释放所有权,将所有者标记为空 safe_ptr<T>& Release() { if ( AuthT && (AuthT->author==&AuthT) ) { SAFEPTR_TRACE("释放前 AuthT:%08X author:%08X, data:%d/n",&AuthT, AuthT->author,AuthT->data); AuthT->author=0; //释放权限 SAFEPTR_TRACE("释放后 AuthT:%08X author:%08X, data:%d/n",&AuthT, AuthT->author,AuthT->data); } return *this; } //重载赋值运算符为引用赋值运算符 safe_ptr<T>& operator=(const safe_ptr<T> &Y) { SAFEPTR_TRACE("赋值前 Y.AuthT:%08X Y.author:%08X, Y.data:%d/n",&Y.AuthT, Y.AuthT->author,Y.AuthT->data); //判断对象是否为空,且所指向的数据内的拥有着标记为自己 if ( AuthT && (AuthT->author==&AuthT) ) { delete AuthT; //释放原来数据空间 AuthT=NULL; } //控制权转移给AutoT AuthT=Y.AuthT; AuthT->author=&AuthT; SAFEPTR_TRACE("赋值后 AuthT:%08X author:%08X, data:%d/n",&AuthT, AuthT->author,AuthT->data); return *this; } //强制拷贝运算符号 safe_ptr<T>& operator <<= (const safe_ptr<T> &Y) { if ( AuthT && (AuthT->author==&AuthT) ) { memcpy(&AuthT->data,&Y.AuthT->data,sizeof(T)); }else{ AuthT = new safe<T>(); AuthT->author=&AuthT; memcpy(&AuthT->data,&Y.AuthT->data,sizeof(T)); } //若原来所有者为空,则删除指针指向的数据 if (Y.AuthT->author==0) { delete Y.AuthT; } } //判断是否空指针 operator bool() { return AuthT!=NULL; } //下面3个是为了使用data数据方便 T& operator*() { return (*get()); } T *operator->() { return (get()); } T *get() { return (&AuthT->data); } }; struct t { char name[20]; char msg[100]; }; safe_ptr<int> fun1() { TRACE("调用函数fun1()/n"); safe_ptr<int> ia(true); *ia = 14; TRACE("函数结束fun1()/n"); return ia.Release(); }; safe_ptr<t> fun2() { TRACE("调用函数fun2()/n"); safe_ptr<t> ta(true); strcpy(ta->msg,"hello!"); strcpy(ta->name,"yxw."); TRACE("函数结束fun2()/n"); return ta.Release(); }; int main(int argc, char* argv[]) { //整数测试 safe_ptr<int> ia; ia=fun1(); if(ia) { TRACE("%d/n",*ia); }else { TRACE("ia isNULL/n"); } //结构体测试 safe_ptr<t> ta; ta=fun2(); if(ta) { TRACE("%s %s/n",ta->msg,ta->name); }else { TRACE("ta isNULL/n"); } return 0; }