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

2019-07-22  本文已影响0人  unique_可乐

参考网址: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()
上一篇下一篇

猜你喜欢

热点阅读