实现代码:
// mySharedPtr.h
#include <future>
#include <assert.h>
using namespace std;
template<typename T>
class mySharedPtr {
public:
mySharedPtr(T* ptr = nullptr) : ptr_(ptr) {
if (ptr_) {
cnt_ = new int(1);
} else {
cnt_ = new int(0);
}
pmutex_ = new mutex();
}
~mySharedPtr() {Release();}
mySharedPtr(const mySharedPtr<T>& shared_ptr) {
ptr_ = shared_ptr.ptr_;
cnt_ = shared_ptr.cnt_;
pmutex_ = shared_ptr.pmutex_;
AddCnt();
}
mySharedPtr<T>& operator = (const mySharedPtr& shared_ptr) {
if (shared_ptr != this) {
Release();
ptr_ = shared_ptr.ptr_;
cnt_ = shared_ptr.cnt_;
pmutex_ = shared_ptr.pmutex_;
AddCnt();
}
return *this;
}
T* get() {
return ptr_;
}
int Count() {
return *cnt_;
}
T* operator -> () {
assert(ptr_ != nullptr);
return ptr_;
}
T& operator * () {
assert(ptr_ != nullptr);
return *ptr_;
}
private:
void AddCnt() {
lock_guard<mutex> lock(*pmutex_);
++(*cnt_);
}
void Release() {
bool delete_flag = false;
{
lock_guard<mutex> lock(*pmutex_);
if (ptr_ && --(*cnt_) == 0) {
delete ptr_;
delete cnt_;
delete_flag = true;
}
}
if (delete_flag) delete pmutex_;
}
private:
int* cnt_;
T* ptr_;
mutex* pmutex_;
} ;
测试:
// object.cpp
#include <iostream>
#include "mySharedPtr.h"
using namespace std;
class Solution {
public:
bool Judge() {
cout << val << "!!!!!!!!!!!1" << endl;
return true;
}
private:
int val = 111;
};
int main()
{
mySharedPtr<Solution> sp1(new Solution());
cout << sp1.Count() << endl;
sp1->Judge();
(*sp1).Judge();
// error: ‘class mySharedPtr<Solution>’ has no member named ‘Judge’
// sp1.Judge();
{
mySharedPtr<Solution> sp2(sp1);
cout << sp1.Count() << endl;
cout << sp2.Count() << endl;
}
cout << sp1.Count() << endl;
mySharedPtr<Solution> sp3;
sp3->Judge();
return 0;
}
输出:
有两点要注意:
在智能指针里,操作符->与操作符.的区别:
智能指针有一个通用的规则,就是->表示用于调用指针原有的方法,而.则表示调用智能指针本身的方法。
断言assert的使用,能够确保空指针的使用。
当然了,这个实现其实是很粗暴的,只是一种思想的体现,源码肯定比这复杂的多。
比如上面的
sp1.Count();
sp1->Judge();
的区别。
参考文章:
https://blog.csdn.net/solstice/article/details/8547547:讨论共享指针是线程不安全的例子;
https://blog.csdn.net/loreal8/article/details/107617782:讨论计数线程安全。