美文网首页
C++新特性【智能指针内存管理】

C++新特性【智能指针内存管理】

作者: unique_可乐 | 来源:发表于2019-07-22 16:35 被阅读0次

    参考网址:https://www.cnblogs.com/feng-sc/p/5710724.html#title13

    1、std::shared_ptr

    std::make_shared封装了new方法,第一次调用make_shared<>创建类实例时,会对指针的引用计数加1,当检测到引用计数为0,调用析构函数来delete之前std::make_shared创建的指针
    代码示例:

    #include <iostream>
    #include <memory>
    
    using namespace std;
    
    class TestA
    {
    
    public:
        TestA() {
            cout << "testA()" << endl;
        }
        ~TestA() {
            
            cout << "~testA()" << endl;
        }
    };
    int main() {
        std::shared_ptr<TestA> p1 = std::make_shared<TestA>();
        cout << "1 ref:" << p1.use_count() << endl;
        {
            std::shared_ptr<TestA> p2 = p1;
            cout << "2 ref:" << p1.use_count() << endl;
        }
        cout << "3 ref:" << p1.use_count() << endl;
    
        //getchar();
        //system("pause");
        return 0;
    }
    

    运行结果:

    testA()
    1 ref:1
    2 ref:2
    3 ref:1
    ~testA()
    

    2、std::weak_ptr

    1)std::weak_ptr与std::shared_ptr最大的差别是在赋值时,不会增加智能指针的计数
    2)解决shared_ptr相互引用问题
    代码示例:

    #include <iostream>
    #include <memory>
    using namespace std;
    
    class TestB;
    class TestA
    {
    public:
        TestA() {
            cout << "testA()" << endl;
        }
        ~TestA() {
            cout << "~testA()" << endl;
        }
        void ReferTestB(shared_ptr<TestB> ptr) {
            mpTestB = ptr;
        }
    private:
        shared_ptr<TestB> mpTestB;
    };
    class TestB {
    public:
        TestB() {
            cout << "TestB()" << endl;
        }
        ~TestB() {
            cout << "~TestB()" << endl;
        }
        void ReferTestB(shared_ptr<TestA> ptr) {
            mpTestA = ptr;
        }
    private:
        shared_ptr<TestA> mpTestA;
    };
    
    int main() {
        std::shared_ptr<TestA> pLocalA = std::make_shared<TestA>();
        std::shared_ptr<TestB> pLocalB = std::make_shared<TestB>();
        cout << "1 ref:" << pLocalA.use_count() << endl;
        cout << "2 ref:" << pLocalB.use_count() << endl;
        pLocalA->ReferTestB(pLocalB);//pLocalB的引用计数加1变成2
        pLocalB->ReferTestB(pLocalA);//pLocalA的引用计数加1变成2
        cout << "3 ref:" << pLocalA.use_count() << endl;
        cout << "4 ref:" << pLocalB.use_count() << endl;
        //system("pause");
        return 0;
    }
    

    运行结果:

    testA()
    TestB()
    1 ref:1
    2 ref:1
    3 ref:2
    4 ref:2
    

    创建的2个对象指针在main调用完成后,没有调用对应的析构函数,为什么?
    pLocalA->ReferTestB(pLocalB)执行后,pLocalB被TestA中的mpTestB引用,pLocalB的引用计数加1变成2,在main函数退出时,pLocalB的引用计数减为1,没有达到调用对应析构函数条件;同理对象指针pLocalA不能走到析构函数中。

    引进weak_ptr来解决上面问题,示例代码:

    class TestA
    {
    public:
        TestA() {
            cout << "testA()" << endl;
        }
        ~TestA() {
            cout << "~testA()" << endl;
        }
        void ReferTestB(shared_ptr<TestB> ptr) {
            mpTestB = ptr;
        }
    private:
        weak_ptr<TestB> mpTestB;
    };
    class TestB {
    public:
        TestB() {
            cout << "TestB()" << endl;
        }
        ~TestB() {
            cout << "~TestB()" << endl;
        }
        void ReferTestB(shared_ptr<TestA> ptr) {
            mpTestA = ptr;
        }
    private:
        weak_ptr<TestA> mpTestA;
    };
    
    int main() {
        std::shared_ptr<TestA> pLocalA = std::make_shared<TestA>();
        std::shared_ptr<TestB> pLocalB = std::make_shared<TestB>();
        cout << "1 ref:" << pLocalA.use_count() << endl;
        cout << "2 ref:" << pLocalB.use_count() << endl;
        pLocalA->ReferTestB(pLocalB);
        pLocalB->ReferTestB(pLocalA);
        cout << "3 ref:" << pLocalA.use_count() << endl;
        cout << "4 ref:" << pLocalB.use_count() << endl;
        //system("pause");
        return 0;
    }
    

    运行结果:

    testA()
    TestB()
    1 ref:1
    2 ref:1
    3 ref:1
    4 ref:1
    ~TestB()
    ~testA()
    

    lock()的作用:
    把std::weak_ptr类型转换成std::shared_ptr类型,然后对TestA对象进行调用

    class TestB;
    class TestA
    {
    public:
        TestA() {
            cout << "testA()" << endl;
        }
        ~TestA() {
            cout << "~testA()" << endl;
        }
        void ReferTestB(shared_ptr<TestB> ptr) {
            mpTestB = ptr;
        }
        void TestWork(){
            std::cout << "TestA::TestWork()" << std::endl;
        }
    private:
        weak_ptr<TestB> mpTestB;
    };
    class TestB {
    public:
        TestB() {
            cout << "TestB()" << endl;
        }
        ~TestB() {
            //把std::weak_ptr类型转换成std::shared_ptr类型,然后对TestA对象进行调用
            std::shared_ptr<TestA> tmp = mpTestA.lock();
            tmp->TestWork();
            std::cout << "ref of mpTestA:" << tmp.use_count() << std::endl;
            cout << "~TestB()" << endl;
        }
        void ReferTestB(shared_ptr<TestA> ptr) {
            mpTestA = ptr;
        }
        void TestWork() {
            std::cout << "TestB::TestWork()" << std::endl;
        }
    private:
        weak_ptr<TestA> mpTestA;
    };
    
    int main() {
        std::shared_ptr<TestA> pLocalA = std::make_shared<TestA>();
        std::shared_ptr<TestB> pLocalB = std::make_shared<TestB>();
        cout << "1 ref:" << pLocalA.use_count() << endl;
        cout << "2 ref:" << pLocalB.use_count() << endl;
        pLocalA->ReferTestB(pLocalB);
        pLocalB->ReferTestB(pLocalA);
        cout << "3 ref:" << pLocalA.use_count() << endl;
        cout << "4 ref:" << pLocalB.use_count() << endl;
        //system("pause");
        return 0;
    }
    

    运行结果:

    testA()
    TestB()
    1 ref:1
    2 ref:1
    3 ref:1
    4 ref:1
    TestA::TestWork()
    ref of mpTestA:2
    ~TestB()
    ~testA()
    

    相关文章

      网友评论

          本文标题:C++新特性【智能指针内存管理】

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