智能指针初学

Posted weiyouqing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了智能指针初学相关的知识,希望对你有一定的参考价值。

参考链接:https://blog.csdn.net/kang_tju/article/details/76515894

     https://www.cnblogs.com/TenosDoIt/p/3456704.html

1.auto_ptr:

#include <iostream>
#include <memory>
using namespace std;

class test
{
public:
    test(int cvalue)
    {
        m_value = cvalue;
        cout << "creat test" << m_value <<endl;
    }
    ~test()
    {
        cout << "destory test" << m_value << endl;
    }
    void setValue(int value)
    {
        m_value = value;
    }

    void getValue()
    {
        cout << m_value << endl;
    }
private:
    int m_value;
};

void testFunc(auto_ptr<test> obj)
{
    obj->getValue();
}

int main()
{
    auto_ptr<test> ptest(new test(1));
    auto_ptr<test> ptest2(new test(2));

    ptest->setValue(3);
    ptest->getValue();

    ptest2->setValue(4);
    ptest2->getValue();

    ptest = ptest2;        //将ptest2的所有权移交给了ptest.此时ptest之前的资源被析构掉了
    ptest->getValue();

    testFunc(ptest);
    //cout << ptest->getValue() << endl;    //这句话是错误的,应为auto_ptr在函数参数传递的时候,进行了一个复制。

    if (ptest2.get() == NULL)
        cout << "ptest2.get() is NULL" << endl;
    system("pause");
    return 0;
}

 输出结果:

            技术分享图片

2.unique_ptr:独享所有权的语义

 

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class test
{
public:
    test(int cvalue)
    {
        m_value = cvalue;
        cout << "creat test" << m_value <<endl;
    }
    ~test()
    {
        cout << "destory test" << m_value << endl;
    }
    void setValue(int value)
    {
        m_value = value;
    }

    void getValue()
    {
        cout << m_value << endl;
    }
private:
    int m_value;
};

void testFunc(auto_ptr<test> obj)
{
    obj->getValue();
}

void testFunc(unique_ptr<test> obj)
{
    obj->getValue();
}

int main()
{
//unique_ptr:
    unique_ptr<test> uni_test(new test(0));
    unique_ptr<test> uni_test1(new test(3));
    unique_ptr<test> tPtr;    //这里没有分配内存,因此是没有构造的;

    cout << sizeof(uni_test)<<endl;
    cout << sizeof(tPtr) << endl;

    uni_test->getValue();
    uni_test->setValue(1);
    uni_test->getValue();

    tPtr = move(uni_test);
    tPtr->setValue(2);
    tPtr->getValue();

//unique_ptr能够放在vector中
    vector<unique_ptr<test>> vec;
    vec.push_back(move(tPtr));
    vec.push_back(move(uni_test1));

    for (int i = 0 ; i < vec.size() ; i++)
    {
        vec[i]->getValue();
    }
        system("pause");
        return 0;
}    

3.shaerd_ptr基于共享语义实现

 

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class test
{
public:
    test(int cvalue)
    {
        m_value = cvalue;
        cout << "creat test" << m_value <<endl;
    }
    ~test()
    {
        cout << "destory test" << m_value << endl;
    }
    void setValue(int value)
    {
        m_value = value;
    }

    void getValue()
    {
        cout << m_value << endl;
    }
private:
    int m_value;
};

void testFunc(auto_ptr<test> obj)
{
    obj->getValue();
}

void testFunc(unique_ptr<test> obj)
{
    obj->getValue();
}

int main()
{
    shared_ptr<test> p_test0(new test(3));
    p_test0->getValue();

    cout << "p_test0.use_count() = " << p_test0.use_count() << endl;

    shared_ptr<test> p_test1 = p_test0;

    cout << "p_test0.use_count() = " << p_test0.use_count() << endl;
    cout << "p_test1.use_count() = " << p_test1.use_count() << endl;

    shared_ptr<test> p_test2 = make_shared<test>(4);
    p_test2->getValue();

    p_test1 = p_test2;
    cout << "p_test2.use_count() = " << p_test2.use_count() << endl;
    cout << "p_test1.use_count() = " << p_test1.use_count() << endl;

    cout << "p_test0.use_count() = " << p_test0.use_count() << endl;
    system("pause");
    return  0;
}

 输出结果:

  技术分享图片

4. weak_ptr

5. 使用智能指针注意:

  • 当指针不具有共享语义的时候,使用了shared_ptr。此时使用unique_ptr即可
  • 既然shared_ptr是具有共享语义的,那么对于多线程访问的安全性如何保证!
  • auto_ptr禁止使用,作为独占语义的智能指针,我们使用unique_ptr即可
  • 关于shared_ptr,尽量使用make_shared来进行初始化。
  • 智能指针在创建对象时,如果使用裸指针,应该确保裸指针之后都不会再使用。
  • 关于shared_ptr,使用get方法获得裸指针是非常危险的行为!禁止!
  • 关于shared_ptr,当使用shared_ptr指向动态数组的时候,需要定义自己的deleter.
  • 在使用shared_ptr时形成循环引用,使用weak_ptr来解决这个问题。
  • 关于unique_ptr,如果使用release方法之后,unique_ptr从销毁指针的责任中解脱出来,此时还需要手动销毁裸指针。
  • 关于weak_ptr,使用的时候,必须调用lock方法来判断它的有效性。

  智能指针是一种工具,具体来说是一种类型,用来管理动态内存(dynamic memory or heap memory)。当然,你也可以用new和delete来管理,但是后者比较容易出bug。

  智能指针的行为类似常规指针,重要的区别它负责自动释放所指向的对象。C++11提供的三种智能指针分别是unique_ptr,shared_ptr和weak_ptr。

  区别是,前者实现了独占语义,后两者则实现了共享语义。语义上的具体体现就是是否允许复制和赋值的语义。在底层实现上是否允许多个指针指向同一个对象。

  shared_ptr和weak_ptr的区别是,强引用和弱引用的区别。具体表现为是否增加所指向对象的ref count.

 

以上是关于智能指针初学的主要内容,如果未能解决你的问题,请参考以下文章

指针辨析:悬垂指针哑指针野指针智能指针

初学c语言指针问题

如何设置 vscode 的代码片段,以便在自动完成后自动触发 vscode 的智能感知?

更新:C++ 指针片段

从C语言到C++你必须学会的---动态内存和智能指针

从C语言到C++你必须学会的---动态内存和智能指针