智能指针shared_ptr

shared_ptr的引用计数是原子实现,在多线程情况下,如果智能指针对象的状态发生变化,需要加锁。

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(sharedptr)

set(PROJECT_VERSION 1.0)

configure_file(
                ${PROJECT_SOURCE_DIR}/config.h.in
                ${PROJECT_SOURCE_DIR}/config.h
            )

set (SRC_LIST ./sharedPtr.cpp)

set (CMAKE_CXX_STANDARD 17)
set (CMAKE_BUILD_TYPE DEBUG)
add_compile_options( -g -Wall -Wextra -pedantic)

add_executable(test ${SRC_LIST})

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

config.h.in

#ifndef CONFIG_H
#define CONFIG_H

#define PROJECT_NAME "@PROJECT_NAME@"
#define PROJECT_VERSION "@PROJECT_VERSION@"

#endif

sharedPtr.cpp

#include <iostream>
using namespace std;

template <class T>
class SharedPtr {
private:
    T* ptr;    // 指向管理的对象
    size_t* refCount;    //指向引用计数

    //释放资源
    void Release()
    {
        if (refCount) {
            (*refCount)--;
            if (*refCount == 0) {
                delete ptr;
                delete refCount;
            }
        }
    }
public:
    //  构造函数
    explicit SharedPtr(T* p = nullptr) : ptr(p), refCount(new size_t(1))
    {
        if (ptr == nullptr) {
            *refCount = 0;
        }
    }
    //  拷贝构造函数
    SharedPtr(const SharedPtr& other) : ptr(other.ptr), refCount(other.refCount)
    {
        if (refCount) {
            (*refCount)++;
        }
    }
    //拷贝赋值运算符函数
    SharedPtr& operator=(const SharedPtr& other)
    {
        if (this != &other) {
            Release();    // 释放当前资源
            ptr = other.ptr;
            refCount = other.refCount;
            if (refCount) {
                (*refCount)++;
            }
        }
        return *this;
    }
    // 移动构造
    SharedPtr(SharedPtr&& other) noexcept : ptr(other.ptr), refCount(other.refCount)
    {
        other.ptr = nullptr;
        other.refCount = nullptr;
    }

    // 移动赋值运算符
    SharedPtr& operator=(SharedPtr&& other) noexcept {
        if (this != &other) {
            Release();
            ptr = other.ptr;
            refCount = other.refCount;
            other.ptr = nullptr;
            other.refCount = nullptr;
        }
        return *this;
    }
    // 析构函数
    ~SharedPtr()
    {
        Release();
    }

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

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

    // 获得引用计数
    size_t UseCount() const
    {
        return refCount ? *refCount : 0;
    }

    bool IsNull() const
    {
        return ptr == nullptr;
    }
};

class MyClass
{
public:
    MyClass()
    {
        cout << "MyClass constructed" << endl;
    }

    ~MyClass()
    {
        cout << "MyClass destroyed" << endl;
    }

    void DoSomething()
    {
        cout << "Doing something" << endl;
    }
};

int main()
{
    SharedPtr<MyClass> ptr1(new MyClass);
    // SharedPtr<MyClass> ptr1(new MyClass);
    std::cout << "ptr1 use_count: " << ptr1.UseCount() << endl;
    {
        // 拷贝构造
        auto ptr2 = ptr1;
        std::cout << "ptr1 use_count: " << ptr1.UseCount() << endl; // 2
        std::cout << "ptr2 use_count: " << ptr2.UseCount() << endl; // 2

        // 使用指针
        ptr2->DoSomething();
    }  // ptr2 离开作用域,引用计数减 1

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

    // 移动语义
    SharedPtr<MyClass> ptr3 = std::move(ptr1);
    std::cout << "ptr1 is_null: " << ptr1.IsNull() << endl; // true
    std::cout << "ptr3 use_count: " << ptr3.UseCount() << endl; // 1
    return 0;
} // ptr3 离开作用域,引用计数降为 0,对象被销毁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值