本文共 2201 字,大约阅读时间需要 7 分钟。
仿函数其实是一个模版类,并不是真正意义上的函数,但很类似函数,可以重载调用’()‘,其实质是在调用时,产生一个临时对象,然后该对象去调用重载的’()’算符。
说了这么多想必你还不是很清楚下面我们拿SharedPtr举个例子
先了解一下什么是小白的(不要笑)
SharedPtr简单来说就是一个智能指针,他能够自动释放你所申请的空间,他能像普通指针一样可以被解引用和’->’用看了SharedPtr的小白实现后你肯定会发现如果指针是一个FILE*或者new string[n]怎么办这时小白实现的SharedPtr就相形见拙了
然而仿函数就可帮我们来解决这些何时用delete,何时用delete[],何时用fclose问题如果
下面就让我们利用仿函数来改进一下小白实现的SharedPtr
//它是仿函数模仿 delete []_ptr templateclass DelArrayPtr //如果申请的是一串儿数组,用delete[] { public: void operator()(T* ptr) //关键的一步重载() { delete []ptr; } }; //它是仿函数模仿 delete _ptr template //如果申请的是某一类型,用delete class DelPopPtr { public: void operator()(T* ptr) //关键的一步重载() { delete ptr; } }; //它是仿函数模仿 fclose(FILE* _ptr) template class Fclose { void operator()(FILE* Ptr) //关键的一步重载() { fclose(ptr); } }; template > //注意这里我们加入了一个模板类,默认参数为delete class SharedPtr { public: SharedPtr(T* ptr,Delete del) :_ptr(ptr) ,_refCount(new int(1)) //此时有一个指针指向这块儿被开辟的空 ,_del(del) {} SharedPtr(SharedPtr & Sp) :_ptr(NULL) ,_refCount(new int(0)) { _ptr = Sp._ptr; //浅拷贝 _refCount = Sp._refCount; ++Sp._refCount[0]; //计数器加一 } SharedPtr & operator=(SharedPtr & Sp) { if (_ptr != Sp._ptr) { Release(); _ptr = Sp._ptr; //浅拷贝 _refCount = Sp._refCount; ++Sp._refCount[0]; //计数器加一 } return *this; } void Release() { if (0 == --_refCount[0]) //若_ptr维护的这段空间还有别的指针维护则不释放,else释放空间 { printf("delete:0x%p\n", _ptr); _del(_ptr); delete _refCount; } } T* operator->() //'*'/'->'运算符重载,让SharedPtr类的对象能像普通指针一样使用 { return _ptr; } T& operator*() { return *_ptr; } ~SharedPtr() { Release(); } protected: T* _ptr; //智能指针 int* _refCount; //计数器 Delete _del; //仿函数 };
//new 10 个string释放时报错 DelPopPtrp_str; SharedPtr > sp1(new string[10], p_str);
为什么会报错呢 因为我们new[] 却用delete
//这里我们用delete[]发现并不会报错 DelArrayPtrp_str_arr; SharedPtr > sp1(new string[10], p_str_arr);
转载地址:http://rvgbb.baihongyu.com/