返回

手写智能指针剖析shared_ptr与weak_ptr

后端

智能指针是C++中非常有用的工具,它可以帮助我们自动管理内存,避免内存泄漏和悬垂指针等问题。在C++11中,引入了两种常用的智能指针:shared_ptr和weak_ptr。shared_ptr可以指向一个对象并共享它的所有权,而weak_ptr则可以指向一个对象而不拥有它,从而避免循环引用。

shared_ptr

shared_ptr是一个智能指针,它可以指向一个对象并共享它的所有权。shared_ptr内部有一个引用计数,当shared_ptr指向的对象被销毁时,引用计数减一,当引用计数为0时,对象被销毁。

weak_ptr

weak_ptr是一个智能指针,它可以指向一个对象而不拥有它。weak_ptr内部有一个weak_ptr_impl对象,weak_ptr_impl对象指向一个shared_ptr对象,shared_ptr对象指向真正要管理的对象。当weak_ptr指向的对象被销毁时,weak_ptr_impl对象将指向一个空的shared_ptr对象,当空的shared_ptr对象被销毁时,weak_ptr_impl对象也被销毁。

shared_ptr和weak_ptr的区别

特点 shared_ptr weak_ptr
所有权 共享
引用计数
使用场景 指向需要共享的对象 指向不需要拥有但需要追踪的对象

手写shared_ptr和weak_ptr

为了更好地理解shared_ptr和weak_ptr,我们可以尝试手写简易的shared_ptr和weak_ptr。

// shared_ptr.h
template<typename T>
class shared_ptr {
public:
    shared_ptr(T* ptr = nullptr) : _ptr(ptr), _ref_count(new int(1)) {}
    shared_ptr(const shared_ptr<T>& other) : _ptr(other._ptr), _ref_count(other._ref_count) {
        ++(*_ref_count);
    }
    ~shared_ptr() {
        if (--(*_ref_count) == 0) {
            delete _ptr;
            delete _ref_count;
        }
    }

    T* get() const { return _ptr; }
    T& operator*() const { return *_ptr; }
    T* operator->() const { return _ptr; }

private:
    T* _ptr;
    int* _ref_count;
};

// weak_ptr.h
template<typename T>
class weak_ptr {
public:
    weak_ptr(const shared_ptr<T>& other) : _shared_ptr(other) {}

    T* get() const { return _shared_ptr.lock(); }
    T& operator*() const { return *_shared_ptr.lock(); }
    T* operator->() const { return _shared_ptr.lock(); }

private:
    shared_ptr<T> _shared_ptr;
};

手写的shared_ptr和weak_ptr可以实现基本的功能,但是它们并不完整。例如,手写的shared_ptr和weak_ptr没有实现循环引用检测,这可能会导致内存泄漏。

总结

shared_ptr和weak_ptr是C++中非常有用的工具,它们可以帮助我们自动管理内存,避免内存泄漏和悬垂指针等问题。通过手写简易的shared_ptr和weak_ptr,我们可以进一步增强对智能指针的理解。