C++11的智能指针确实带来了很多方便,但是shared_ptr因为要维护很多元信息,会牺牲一些效率,如果大量使用智能指针,一定不要忘记开启编译器的优化选项。。
下面是仿照unique_ptr和shared_ptr的实现。
unique_ptr
#pragma once
namespace m{
template<typename T>
struct DefaultDeleter{
void operator()(T *ptr){
if(ptr!=nullptr){
delete ptr;
ptr = nullptr;
}
}
};
template<typename T,typename Deleter = DefaultDeleter<T>>
class UniquePtr{
T *ptr;
Deleter deleter;
// delete copy constructor and operator=
UniquePtr(const UniquePtr &){}
UniquePtr &operator=(const UniquePtr &){}
public:
UniquePtr():ptr(nullptr){}
UniquePtr(T *_ptr):ptr(_ptr){}
~UniquePtr(){ deleter(ptr); }
//replaces the managed object
void reset(T *_ptr);
//returns a pointer to the managed object and releases the ownership
T *release();
//returns a pointer to the managed object
T *get();
operator bool() const;
T &operator*();
T *operator->();
};
template<typename T,typename Deleter>
void UniquePtr<T,Deleter>::reset(T *_ptr){
if(ptr==_ptr) return ;
T *old_ptr = ptr;
ptr = _ptr;
deleter(old_ptr);
}
template<typename T,typename Deleter>
T *UniquePtr<T,Deleter>::release(){
T *old_ptr = ptr;
ptr = nullptr;
return old_ptr;
}
template<typename T,typename Deleter>
T *UniquePtr<T,Deleter>::get(){
return ptr;
}
template<typename T, typename Deleter>
UniquePtr<T,Deleter>::operator bool() const{
return ptr!=nullptr;
}
template<typename T, typename Deleter>
T &UniquePtr<T,Deleter>::operator*(){
return *ptr;
}
template<typename T, typename Deleter>
T *UniquePtr<T,Deleter>::operator->(){
return ptr;
}
}
shared_ptr
#pragma once
namespace m{
template<typename T>
struct DefaultDeleter{
void operator()(T *ptr){
if(ptr!=nullptr){
delete ptr;
ptr = nullptr;
}
}
};
template<typename T,typename Deleter>
struct Control{
int reference_count;
Deleter deleter;
Control():reference_count(1){}
};
template <typename T,typename Deleter = DefaultDeleter<T>>
class SharedPtr{
T *ptr;
Control<T,Deleter> *ctrl;
public:
SharedPtr():ptr(nullptr),ctrl(new Control<T,Deleter>()){}
SharedPtr(T *_ptr):ptr(_ptr),ctrl(new Control<T,Deleter>()){}
SharedPtr(const SharedPtr<T> &other):ptr(other->ptr),ctrl(other->ctrl){
ctrl->reference_count++;
}
~SharedPtr() {
ctrl->reference_count--;
if(ctrl->reference_count == 0){
ctrl->deleter(ptr);
delete ctrl;
ctrl = nullptr;
}
}
T &operator*(){
return *ptr;
}
T *operator->(){
return ptr;
}
operator bool() const{
return ptr!=nullptr;
}
};
}