美文网首页
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.cnblogs.com/feng-sc/p/5710724.html#title...

  • Rust智能指针

    智能指针 在C/C++中,堆内存的申请和释放都由程序员自己管理,自C++11起,引入了智能指针来协助管理内存。对于...

  • 源码分析shared_ptr实现

    智能指针是C++中一项很常用的技术,合理的使用智能指针可以更方便的管理内存,降低内存泄漏的风险,这里只介绍C++1...

  • 窥见C++11智能指针

    导语: C++指针的内存管理相信是大部分C++入门程序员的梦魇,受到Boost的启发,C++11标准推出了智能指针...

  • 智能指针和垃圾回收

    堆内存管理:智能指针与垃圾回收 显式内存管理 野指针 重复释放 内存泄漏 C++11 的智能指针 unique_p...

  • C++智能指针学习

    C++智能指针学习 [toc] 智能指针内存管理要解决的根本问题是:一个堆对象,在被多个对象引用时,如何释放资源的...

  • Android智能指针分析

    Android智能指针分析总结 什么是智能指针 C++ 指针需要手动释放,否则会造成内存泄露,但是如果项目工程比较...

  • C++这么难,该怎么学?

    C++以其复杂的语法、指针、内存管理、泛型编程等特性难倒了一大批IT学子。小编以CSharp入门,中途转C++的时...

  • C++11(1)-智能指针

    C++裸指针的内存问题有:1、空悬指针/野指针2、重复释放3、内存泄漏4、不配对的申请与释放 使用智能指针可以有效...

  • C++ 智能指针

    智能指针 传统指针存在的问题需要手动管理内存容易发生内存泄露(忘记释放,出现异常等)释放之后产生野指针 智能指针就...

网友评论

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

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