shared_ptr.h

#pragma once

#include <atomic>

template<typename T>
class shared_ptr {
private:
    T* ptr;                               // 指向管理的对象
    std::atomic<std::size_t>* ref_count;  //原子引用计数

    // 释放资源
    void release() {
        if (ref_count && ref_count->fetch_sub(1, std::memory_order_acq_rel) == 1) {
            delete ptr;
            delete ref_count;
        }
    }
public:
    // 默认构造函数
    shared_ptr() : ptr(nullptr), ref_count(nullptr) {}

    // 构造函数
    // explicit 为了防止 shared_ptr<T> s = new int(10);
    explicit shared_ptr(T* p) : ptr(p), ref_count(p ? new std::atomic<std::size_t>(1) : nullptr) {}

    // 析构函数
    ~shared_ptr() {
        release();
    }

    // 拷贝构造函数
    shared_ptr(const shared_ptr<T>& other) : ptr(other.ptr), ref_count(other.ref_count) {
        if (ref_count) {
            ref_count->fetch_add(1, std::memory_order_relaxed); // 引用计数加1
        }
    }

    // 拷贝赋值运算符
    shared_ptr<T>& operator=(const shared_ptr<T>& other) {
        if (this != &other) {
            release();
            ptr = other.ptr;
            ref_count = other.ref_count;
            if (ref_count) {
                ref_count->fetch_add(1, std::memory_order_relaxed); // 引用计数加1
            }
        }
        return *this;
    }

    // 移动构造函数
    shared_ptr(shared_ptr<T>&& other) noexcept : ptr(other.ptr), ref_count(other.ref_count) {
        other.ptr = nullptr;
        other.ref_count = nullptr;
    }

    // 移动赋值运算符
    shared_ptr<T>& operator=(shared_ptr<T>&& other) noexcept {
        if (this != &other) {
            release();
            ptr = other.ptr;
            ref_count = other.ref_count;
            other.ptr = nullptr;
            other.ref_count = nullptr;
        }
        return *this;
    }

    // 解引用运算符
    T& operator*() const {
        return *ptr;
    }

    // 指针运算符
    T* operator->() const {
        return ptr;
    }

    // 取址运算符
    T* get() const {
        return ptr;
    }

    // 引用计数
    std::size_t use_count() const {
        return ref_count ? ref_count->load(std::memory_order_acquire) : 0;
    }

    // 是否为空
    bool unique() const {
        return use_count() == 1;
    }

    // 是否有效
    explicit operator bool() const {
        return ptr != nullptr;
    }

    void reset(T* p = nullptr) {
        release();
        ptr = p;
        ref_count = p ? new std::atomic<std::size_t>(1) : nullptr;
    }
};

example.cpp

#include <iostream>
#include "shared_ptr.h"
#include<thread>
#include<vector>
#include<chrono>

void test_shared_ptr_thread_safety()
{
	shared_ptr<int> ptr(new int(10));

	const int num_threads = 10;
	std::vector<std::thread> threads;
	for (int i = 0; i < num_threads; ++i)
	{
		threads.emplace_back([&ptr]() {
			for (int j = 0; j < 10000; ++j)
			{
				shared_ptr<int> local_ptr(ptr);
				std::this_thread::sleep_for(std::chrono::milliseconds(1));
			}
		});
	}

	for (auto& thread : threads)
	{
		thread.join();
	}

	std::cout << "use_count: " << ptr.use_count() << std::endl;

	if (ptr.use_count() == 1) {
		std::cout << "shared_ptr is thread-safe" << std::endl;
	}
	else {
		std::cout << "shared_ptr is not thread-safe" << std::endl;
	}
}

int main()
{
	shared_ptr<int> ptr1(new int(10));
	std::cout << "ptr1 use_count: " << ptr1.use_count() << std::endl;

	{
		shared_ptr<int> ptr2(ptr1);
		std::cout << "ptr2 use_count: " << ptr2.use_count() << std::endl;
	}

	std::cout << "ptr1 use_count: " << ptr1.use_count() << std::endl;

	test_shared_ptr_thread_safety();

	return 0;
}

最讨厌你,也最喜欢你