环境:
vs2019 clang编译器
my_shared_ptr.h:
ps:不用另外写默认构造函数,shared_ptr(T* p = nullptr)构造函数就包含shared_ptr()了
#pragma once
#include <atomic> //实现引用计数的读写的线程安全性
#include <algorithm>//std::swap
using namespace std;
namespace my_ptr {
template <typename T>
class shared_ptr {
private:
T* _ptr;
atomic<size_t*> cnt;
public:
shared_ptr(T* p = nullptr) :_ptr(p)
{
if (p == nullptr) cnt = new size_t(0);
else cnt = new size_t(1); cout << "shared_ptr(T* p = nullptr)\n";
}
//复制构造
shared_ptr(const shared_ptr& sp) :_ptr(sp._ptr) {
if (sp._ptr == nullptr) *cnt = 0;
else {
auto countp = sp.cnt.load();
(*countp)++;
cnt = countp; //调用cnt.store(countp);
}
cout << "copy_construct_from\n";
}
//移动构造
shared_ptr(const shared_ptr&& sp) :_ptr(sp._ptr), cnt(sp.cnt) {
sp._ptr = nullptr;
sp.cnt = nullptr;
cout << "move_construct_from\n";
};
//析构
~shared_ptr()
{
cout << "~shared_ptr() \n";
if (-- * cnt == 0) {
delete _ptr;
_ptr = nullptr;
delete cnt;
cnt = nullptr;
cout << "delete cnt\n";
}
}
//读取引用计数
int use_count() const noexcept {
return static_cast<int>(*cnt);
}
//是否独占
bool is_unique() noexcept {
return *cnt == 1;
}
//获取原始指针
T* get() const noexcept {
return _ptr;
}
//释放所有权
void reset() noexcept {
shared_ptr().swap(*this);
}
//释放并获得sp的原始指针所有权
void reset(const shared_ptr& sp) {
shared_ptr(sp).swap(*this);
}
//交换对象所有权
void swap(shared_ptr&& sp) noexcept {
T* tmp = _ptr;
_ptr = sp._ptr;
sp._ptr = tmp;
auto countp = cnt.load();
cnt = sp.cnt.load();
sp.cnt = countp;
}
void swap(shared_ptr& sp) noexcept {
this->swap(move(sp));
}
//重载赋值运算符=左值
shared_ptr& operator=(const shared_ptr& sp) noexcept {
shared_ptr(sp).swap(*this);
return *this;
}
//重载赋值运算符=右值
shared_ptr& operator=(const shared_ptr&& sp) noexcept {
shared_ptr(move(sp)).swap(*this);
return *this;
}
//重载*,返回原始指针所指对象/值
T& operator*() const noexcept {
return *get();
}
//重载->,直接返回原始指针
T* operator->() const noexcept {
return get();
}
//重载==,直接比较原始指针是否相同
bool operator==(const shared_ptr& right) const noexcept {
return this->get() == right.get();
}
//重载!=
bool operator!=(const shared_ptr& right) const noexcept {
return this->get() != right.get();
}
//重载<
bool operator<(const shared_ptr& right) const noexcept {
return this->get() < right.get();
}
//重载>
bool operator>(const shared_ptr& right) const noexcept {
return this->get() > right.get();
}
};
}
测试程序:
#include <iostream>
#include "my_shared_ptr.h"
using namespace std;
int main() {
int* p0 = new int(1);
my_ptr::shared_ptr<int> sp(p0);
int* p = sp.get();
cout << "sp.is_unique() " << sp.is_unique() << endl;
cout << "sp.use_count() " << sp.use_count() << endl;
cout << endl;
my_ptr::shared_ptr<int> sp1(sp);
cout << "sp.use_count() " << sp.use_count() << endl;
cout << "sp1.use_count() " << sp1.use_count() << endl;
cout << endl;
cout << "sp1.reset()" << endl;
sp1.reset();
cout << "sp.use_count() " << sp.use_count() << endl;
cout << "sp1.use_count() " << sp1.use_count() << endl;
cout << endl;
cout << "sp1.reset(sp)" << endl;
sp1.reset(sp);
cout << "sp.use_count() " << sp.use_count() << endl;
cout << "sp1.use_count() " << sp1.use_count() << endl;
cout << endl;
my_ptr::shared_ptr<int> sp2(new int(1));
cout << "sp2.use_count() " << sp2.use_count() << endl;
cout << endl;
my_ptr::shared_ptr<int> sp3;
cout << "sp3.use_count() " << sp3.use_count() << endl;
cout << endl;
}
测试结果:
shared_ptr(T* p = nullptr)
sp.is_unique() 1
sp.use_count() 1
copy_construct_from
sp.use_count() 2
sp1.use_count() 2
sp1.reset()
shared_ptr(T* p = nullptr)
~shared_ptr()
sp.use_count() 1
sp1.use_count() 0
sp1.reset(sp)
copy_construct_from
~shared_ptr()
sp.use_count() 2
sp1.use_count() 2
shared_ptr(T* p = nullptr)
sp2.use_count() 1
shared_ptr(T* p = nullptr)
sp3.use_count() 0
~shared_ptr()
~shared_ptr()
delete cnt
~shared_ptr()
~shared_ptr()
delete cnt
注意:如果使用命名空间包含类,则命名空间的定义要放在使用之前的位置。
namespace Test{
...
class A;
}
//使用方式包括
//1.使用整个命名空间
using Test;
//2.使用命名空间部分内容
using Test::A;
//3.不用using直接使用,前面要加 命名空间::
Test::A objA;