0
点赞
收藏
分享

微信扫一扫

c++ 手写智能指针shared_ptr

boom莎卡拉卡 2022-01-31 阅读 40

c++ 手写智能指针shared_ptr

留个坑,回头在填。

#include <utility>
#include <iostream>
#include <cstddef>
#include <string>

template<typename T>
class shared_ptr {
    friend class shared_ptr;
    public:
        shared_ptr(T* ptr = nullptr) : m_ref(nullptr), m_obj(ptr) {
            std::cout << "构造函数" << std::endl;
            if(ptr) {
                m_ref = new size_t;
                *m_ref = 1;
            }
        }
        
        ~shared_ptr() noexcept {
            std::cout << "析构函数" << std::endl;
            if(m_ref) {
                --(*m_ref);
            }
            clearMem();
        }
        
        shared_ptr(const shared_ptr<T>& other) {
            std::cout << "拷贝构造函数" << std::endl;
            m_ref = other.m_ref;
            ++ (*m_ref);
            m_obj = other.m_obj;
        }

        shared_ptr& operator=(const shared_ptr<T>& other) {
            std::cout << "赋值运算符" << std::endl;
            if(m_obj == other.m_obj) {
                return *this;
            }
            if(m_obj) {
                --(*m_ref);
                clearMem();
            }
            m_ref = other.m_ref;
            m_obj = other.m_obj;
            ++ (*m_ref);
            return *this;
        }
        
        shared_ptr(shared_ptr<T>&& other) : m_ref(nullptr), m_obj(nullptr){
            std::cout << "移动构造函数" << std::endl;
            other.swap(*this);
        }
        
        shared_ptr& operator=(shared_ptr<T>&& other) {
            std::cout << "移动赋值运算符" << std::endl;
            if(m_obj) {
                --(*m_ref);
                clearMem();
            }
            other.swap(*this);
            return *this;
        }
        
        T& operator*() const { return *m_obj;}
        T* operator->() const { return m_obj;}
        operator bool() const { return m_obj;}
        
        void clearMem() noexcept {
            std::cout << "清理内存" << std::endl;
            if(!m_ref) {
                return;
            }
            if(*m_ref == 0 && m_obj) {
                delete m_ref;
                delete m_obj;
                m_ref = nullptr;
                m_obj = nullptr;
            }
        }
        
        void swap(shared_ptr& other) {
            if(&other == this) {
                return;
            }
            std::swap(this->m_obj, other.m_obj);
            std::swap(this->m_ref, other.m_ref);
        }
        
        T* get() {
            return m_obj;
        }
        
        void getMessage(const std::string& name) {
            if(m_ref) {
                std::cout << name << " ref " << m_ref << ": " << *m_ref << std::endl;
                return;
            }
            std::cout << name << " nullptr" << std::endl;
        }
        
        private:
            size_t* m_ref;
            T* m_obj;
};


struct person {
    int age = 0;
    bool sex = 0;
    person(int a, bool s) : age(a), sex(s) {}
};


int main() {
    std::cout << "---------测试构造函数----------" << std::endl;
    shared_ptr<person> p1(new person(10, true));    // 测试构造函数
    p1.getMessage("p1");
    std::cout << "-------测试拷贝构造函数--------" << std::endl;
    shared_ptr<person> p2(p1);                      // 测试拷贝构造函数
    p1.getMessage("p1");
    p2.getMessage("p2");
    shared_ptr<person> p3(new person(9, false));    
    p3.getMessage("p3");
    std::cout << "------测试重载赋值运算符-------" << std::endl;
    p1 = p3;                                        // 测试重载赋值运算符
    p1.getMessage("p1");
    p2.getMessage("p2");
    p3.getMessage("p3");
    std::cout << "--------测试移动构造函数-------" << std::endl;
    shared_ptr<person> p4(std::move(p3));           // 测试移动构造
    p1.getMessage("p1");
    p2.getMessage("p2");
    p3.getMessage("p3");
    p4.getMessage("p4");
    std::cout << "--------测试移动赋值运算符-------" << std::endl;
    p3 = std::move(p1);                             // 移动赋值运算符
    p1.getMessage("p1");
    p2.getMessage("p2");
    p3.getMessage("p3");
    p4.getMessage("p4");
    std::cout << "----------测试*和->的重载-------" << std::endl;
    std::cout << "*: " << p3->age << std::endl;
    std::cout << "->: " << (*p3).age << std::endl;
    return 0;
}

输出

---------测试构造函数----------
构造函数
p1 ref 0x5598a590a2e0: 1
-------测试拷贝构造函数--------
拷贝构造函数
p1 ref 0x5598a590a2e0: 2
p2 ref 0x5598a590a2e0: 2
构造函数
p3 ref 0x5598a590a320: 1
------测试重载赋值运算符-------
赋值运算符
清理内存
p1 ref 0x5598a590a320: 2
p2 ref 0x5598a590a2e0: 1
p3 ref 0x5598a590a320: 2
--------测试移动构造函数-------
移动构造函数
p1 ref 0x5598a590a320: 2
p2 ref 0x5598a590a2e0: 1
p3 nullptr
p4 ref 0x5598a590a320: 2
--------测试移动赋值运算符-------
移动赋值运算符
p1 nullptr
p2 ref 0x5598a590a2e0: 1
p3 ref 0x5598a590a320: 2
p4 ref 0x5598a590a320: 2
----------测试*->的重载-------
*: 9
->: 9
析构函数
清理内存
析构函数
清理内存
析构函数
清理内存
析构函数
清理内存
举报

相关推荐

0 条评论