#include<iostream>
class SharedCount{
public:
SharedCount():count_(1){}
void AddCount(){
++count_;
}
long ReduceCount(){
return --count_;
}
long GetCount() const{
return count_;
}
template<typename T>
friend class SharedPtr;
private:
long count_;
};
template<typename T>
class SharedPtr{
public:
explicit SharedPtr(T *ptr=nullptr):ptr_(ptr){
if(ptr_){
rel_ = new SharedCount();
}else{
rel_ = nullptr;
}
};
~SharedPtr(){
if(rel_ && !rel_->ReduceCount()){
delete ptr_;
delete rel_;
}
}
SharedPtr(const SharedPtr& other){
rel_ = other.rel_;
if(rel_){
rel_->AddCount();
}
ptr_ = other.ptr_;
}
SharedPtr(SharedPtr&& other){
ptr_ = other.ptr_;
rel_ = other.rel_;
other.ptr_ = nullptr;
other.res_ = nullptr;
}
SharedPtr& operator=(SharedPtr& rhs){
if(ptr_ != rhs.ptr_){
if(rel_ && !rel_->ReduceCount()){
delete ptr_;
delete rel_;
}
rhs.rel_->AddCount();
ptr_ = rhs.ptr_;
rel_ = rhs.rel_;
}
return *this;
}
T* Get() const{
return ptr_;
}
long UseCount() const{
if(ptr_){
return rel_->GetCount();
}else{
return 0;
}
}
T& operator*() const{
return *ptr_;
}
T* operator->() const{
return ptr_;
}
operator bool() const{
return ptr_;
}
private:
T *ptr_;
SharedCount *rel_;
};
int main(){
SharedPtr<int> sp1(new int(5));
SharedPtr<int> sp2;
std::cout << "sp1.use_count: " << sp1.UseCount() << std::endl;
std::cout << "sp2.use_count: " << sp2.UseCount() << std::endl;
sp2 = sp1;
std::cout << "sp1.use_count: " << sp1.UseCount() << std::endl;
std::cout << "sp2.use_count: " << sp2.UseCount() << std::endl;
SharedPtr<int> sp3(sp2);
std::cout << "sp1.use_count: " << sp1.UseCount() << std::endl;
std::cout << "sp2.use_count: " << sp2.UseCount() << std::endl;
std::cout << "sp3.use_count: " << sp3.UseCount() << std::endl;
return 0;
}
