美文网首页
Unique_ptr和Share_ptr的代码实现

Unique_ptr和Share_ptr的代码实现

作者: Magic11 | 来源:发表于2019-12-23 15:45 被阅读0次

    unique_ptr的代码实现:

    #include <iostream>
    
    using namespace std;
    
    class Person {
    public:
        char* name = "json";
        int age = 20;
    };
    
    template <typename T>
    class UniquePtr {
    public:
        explicit UniquePtr(T *ptr = nullptr)
            : m_ptr(ptr) {
        }
        
        ~UniquePtr() {
            if (m_ptr)
                delete m_ptr;
        }
    
        UniquePtr(UniquePtr&& uPtr) {
            m_ptr = uPtr.m_ptr;
            uPtr.m_ptr = nullptr;
        }
    
        UniquePtr& operator=(UniquePtr&& uPtr) {
            if (this == &uPtr) {
                return *this;
            }
            if (m_ptr)
                delete m_ptr;
            m_ptr = uPtr.m_ptr;
            uPtr.m_ptr = nullptr;
            return *this;
        }
    
        UniquePtr(const UniquePtr& ptr) = delete;   //如果提供了移动构造函数,没有提供拷贝构造函数,拷贝构造函数会被禁用
    
        UniquePtr& operator=(const UniquePtr& ptr) = delete;
    
        T* get() const { return m_ptr;  }
    
        T& operator*() const { return *m_ptr; }
    
        T* operator->() const { return m_ptr; }
    
        operator bool() const { return m_ptr; }
    
    
    private:
        T *m_ptr;
    };
    
    int main() {
        
        {
            UniquePtr<Person> ptr(new Person());
    
            if (ptr) {
                cout << ptr->name << endl;
                cout << ptr->age << endl;
            }
    
            Person *person = ptr.get();
            cout << person->name << endl;
            cout << person->age << endl;
    
            //UniquePtr<Person> ptr1(ptr);   //编译不能通过
    
            UniquePtr<Person> ptr2;
            //ptr2 = ptr;      //编译不能通过
    
            UniquePtr<Person> ptr3(std::move(ptr));
    
            ptr2 = std::move(ptr);
        }
    
        getchar();
    
        return 0;
    }
    

    Share_ptr的代码实现如下:

    class SharedCount {
    public:
        SharedCount() : count_(1) {}
        void addCount() { ++count_; }
        long reduceCount() { return --count_;  }
        long getCount() { return count_; }
    private:
        long count_;
    };
    
    template <typename T>
    class SharedPtr {
    public:
        template<typename U>
        friend class SharedPtr;
    
        SharedPtr(T* ptr = nullptr) : m_ptr(ptr) {
            if (m_ptr)
                m_shareCount = new SharedCount();
        }
    
        ~SharedPtr() {
            if (m_ptr && !m_shareCount->reduceCount()) {
                delete m_ptr;
                m_ptr = nullptr;
                delete m_shareCount;
                m_shareCount = nullptr;
            }
        }
    
        template<typename U>
        SharedPtr(const SharedPtr<U> &sPtr) {
            m_ptr = sPtr.m_ptr;
            if (m_ptr) {
                m_shareCount = sPtr.m_shareCount;
                m_shareCount->addCount();
            }
        }
    
        template<typename U>
        SharedPtr(SharedPtr<U> &&sPtr) {
            m_ptr = sPtr.m_ptr;
            if (m_ptr) {
                m_shareCount = sPtr.m_shareCount;
                sPtr.m_ptr = nullptr;
            }
        }
    
        SharedPtr& operator=(SharedPtr other) {
            other.swap(*this);
            return *this;
        }
    
        /*template<typename U>
        SharedPtr& operator=(const SharedPtr<U> &other) {
            if (this == &other) {
                return *this;
            }
            if (m_ptr) {
                if (!m_shareCount->reduceCount()) {
                    delete m_ptr;
                    m_ptr = nullptr;
                }
            }
    
            m_ptr = other.m_ptr;
            if (m_ptr) {
                other.m_shareCount->addCount();
                m_shareCount = other.m_shareCount;
            }
    
        }
    
        template<typename U>
        SharedPtr& operator=(const SharedPtr<U> &&other) {
            if (this == &other) {
                return *this;
            }
            if (m_ptr) {
                if (!m_shareCount->reduceCount()) {
                    delete m_ptr;
                    m_ptr = nullptr;
                }
            }
    
            m_ptr = other.m_ptr;
            if (m_ptr) {
                m_shareCount = other.m_shareCount;
            }
    
            other.m_ptr = nullptr;
    
        }*/
    
    
    
        //方便调试
        long use_count() {
            if (m_ptr) {
                return m_shareCount->getCount();
            }
            else {
                return 0;
            }
        }
    
        T* get() const { return m_ptr;  }
    
        T& operator*() const { return *m_ptr; }
    
        T* operator->() const { return m_ptr;  }
    
        operator bool() const { return m_ptr; }
    
        void swap(SharedPtr& other) {
            using std::swap;
            swap(other.m_ptr, m_ptr);
            swap(other.m_shareCount, m_shareCount);
    
        }
    private:
        T* m_ptr;
        SharedCount* m_shareCount;
    };
    
    class shape {
    public:
        virtual ~shape() {}
    };
    
    class circle : public shape {
    public:
        ~circle() { puts("~circle()"); }
    };
    
    int main() {
        SharedPtr<circle> ptr1(new circle());
        printf("use count of ptr1 is %d\n", ptr1.use_count());
    
        SharedPtr<shape> ptr2;
        printf("use count of ptr2 is %d\n", ptr2.use_count());
    
        ptr2 = ptr1;
        printf("use count of ptr2 is %d\n", ptr2.use_count());
    
        if (ptr1) {
            puts("ptr1 is not empty");
        }
    
        getchar();
    
        return 0;
    }
    

    引自:极客时间/22-现代C++实战30讲/02丨自己动手,实现C++的智能指针.html

    相关文章

      网友评论

          本文标题:Unique_ptr和Share_ptr的代码实现

          本文链接:https://www.haomeiwen.com/subject/ximznctx.html