C++ smart pointer智能指针
在C++中,程序员可以直接操作内存,给编程增加了不少的灵活性。但是灵活性是有代价的,程序员必须负责自己负责释放自己申请的内存,否则就会出现内存泄露。智能指针就是为了解决这个问题而存在的。它和其他指针没有本质的区别,主要的目的就是为了避免悬挂指针、内存泄露的问题。在这里,我使用对象的应用计数做了一个smart pointer,当一个对象还有引用的时候,就不执行释放内存的操作,当引用计数为0时,就执行内存释放操作,并且将指针重置为NULL。
代码如下:
#include <iostream> #include <malloc.h> /* desc: A smart pointer to automatic alloc and dellocat memories. author: justinzhang(uestczhangchao@gmail.com). time: 2015-1-22 09:44:24 */ template <class T> class smartPtr { public: smartPtr() { ptr = NULL; refCnt = (unsigned *) malloc(sizeof(unsigned)); } smartPtr( T * pt) { this->ptr = pt; refCnt = (unsigned *) malloc(sizeof(unsigned)); std::cout << "Enter constructor, refCnt is "<< *refCnt << std::endl; *refCnt = 1; std::cout << "Leave constructor, refCnt is " << *refCnt << std::endl; } smartPtr(smartPtr<T> ©) { ptr = copy.ptr; refCnt = copy.refCnt; std::cout << "Enter copy constructor, refCnt is " << *refCnt << std::endl; ++*refCnt; std::cout << "Leave copy constructor, refCnt is "<< *refCnt << std::endl; } smartPtr<T> & operator=(smartPtr<T> ©) { std::cout << "Enter operator=, refCnt is "<< *copy.refCnt << std::endl; if(this != ©) { ptr = copy.ptr; refCnt = copy.refCnt; ++*refCnt; } std::cout << "Leave operator=, refCnt is " << *refCnt << std::endl; return *this; } ~smartPtr() { std::cout << "Enter destructor, refCnt is " << *refCnt << std::endl; --*refCnt; if(*refCnt == 0 ) { std::cout << "In destructor, refCnt is 0 , this pointer will be freed." << std::endl; if( NULL != ptr ) { delete ptr; ptr = NULL; } if(NULL != refCnt ) { free(refCnt); refCnt = NULL; } } else { std::cout << "Leave destructor, refCnt is " << *refCnt << std::endl; } } T getValue() { return *ptr; } protected: T * ptr; unsigned *refCnt; }; int main() { int * p = new int[2]; smartPtr<int > intSmart(p) ; smartPtr<int> copySmart(intSmart); // copy constructor will be called. smartPtr<int> operatorSmart = intSmart ; // Here the copy consturctor will be called, not the assignment operator. operatorSmart = intSmart; // Here the assignment operator will be called. return 0; }
运行结果如下: