栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

智能指针的总结

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

智能指针的总结

文章目录
      • 定义
      • 分类
      • 智能指针的使用
        • `shared_ptr`
        • `weak_ptr`
        • `unique_ptr`
        • 常见的陷阱
      • 总结
      • 参考地址

定义

智能指针是对象,不是指针。它是通过c++的RAII机制实现的,主要是利用c++对象在释放资源的时候,会自动调用析构函数这一特性。

分类

auto_ptr: 智能指针,c++11已经停用;

shared_ptr: 强智能指针,可以改变资源的引用计数;

weak_ptr: 弱智能指针,不会改变资源的引用计数;

unique_ptr: 独占式强智能指针,只能转移,不能重新赋值;

智能指针的使用 shared_ptr

原理

shared_ptr采用了引用计数器,允许多个指针指向同一个对象。每一个shared_ptr的拷贝都指向相同的内存,并共同维护同一个引用计数器,记录统一使用被引用的次数。每增加一个shared_ptr智能指针对象,new对象指针的引用计数上就加1,当shared_ptr智能指针失效时,new对象指针的引用计数就减1。引用计数归0时,shared_ptr会释放管理的内存空间。

shared_ptr包含2个指针,一个是指向管理的内存空间,一个是指向内存的控制块。

内存控制块包含引用计数器,删除器,分配器等。

class Test
{
public:
    Test();
    ~Test();

    void setFather(std::shared_ptr &value) {
        m_father = value;
    }

    void setSon(std::shared_ptr &value) {
        m_son = value;
    }

private:
    std::shared_ptr m_father;
    std::shared_ptr m_son;
};

void test() {
    Test *ps = new Test();
    std::shared_ptr ptr1(ps);
    std::shared_ptr ptr2(ps);

    ptr1->setFather(ptr2);
    ptr2->setSon(ptr1);

    //计数
    std::cout << ptr1.use_count() << endl;
    //计数
    std::cout << ptr2.use_count() << endl;

    //计数获取原始指针
    std::cout << ptr1.get() < 

从输出信息中可以看到并未调用析构函数。主要是因为互相引用导致。

示例2 测试引用计数问题

//测试shared_ptr的引用计数
void testSharedPtrCount() {
    //不要使用该方式初始化
    Test *ps = new Test();
    std::shared_ptr ptr1(ps);
    std::shared_ptr ptr2(ps);

    //计数
    std::cout << ptr1.use_count() << endl;
    std::cout << ptr2.use_count() << endl;

    std::shared_ptr ptr3(new Test());
    std::shared_ptr ptr4 = ptr3;

    //计数
    std::cout << ptr3.use_count() << endl;
    std::cout << ptr4.use_count() << endl;
}

输出:
1
1
2
2

可以看到使用同一个对象指针初始化的时候,引用计数为1,而使用智能指针初始化智能指针后,引用计数均为2。

智能指针的头文件为:#include

weak_ptr

weak_ptr不能单独作为智能指针使用,只能辅助shared_ptr解决循环依赖的问题。

定义对象的时候使用shared_ptr,引用对象的时候使用weak_ptr。

修改shared_ptr的代码为:

class Test
{
public:
    Test();
    ~Test();

    void setFather(std::shared_ptr &value) {
        m_father = value;
    }

    void setSon(std::shared_ptr &value) {
        m_son = value;
    }

private:
    //修改对象的引用为weak_ptr
    std::weak_ptr m_father;
    std::weak_ptr m_son;
};

输出:
Test Construct()
1
1
0x1091740
0x1091740
Test Destruct()
Test Destruct()

可以看到析构函数被调用了。(即使析构了2次,部分编译器可能不会出现析构错误信息)

unique_ptr

unique_ptr是独占型的强智能指针。独占型就是不允许多个智能指针指向同一块内存空间,也不支持拷贝,复制。

示例1 独占性

//测试uniqueptr
void testUniquePtr() {
    Test *ps = new Test();
    std::unique_ptr ptr1(ps);
    //编译期间就出现错误
    std::unique_ptr ptr2 = ptr1;

    std::cout << ptr1.get() << endl;
    std::cout << ptr2.get() << endl;
}

**示例2 move **

//测试unique_ptr的转移
void testUniquePtrMove() {
    Test *ps = new Test();
    std::unique_ptr ptr1(ps);

    std::cout << "Ptr1: " << ptr1.get() << endl;

    std::unique_ptr ptr2(ps);
    ptr2 = std::move(ptr1);

     std::cout << "Ptr1: "  << ptr1.get() << endl;
     std::cout << "Ptr2: "  << ptr2.get() << endl;
}

//输出
Test Construct()
Ptr1: 0x761740
Test Destruct()
Ptr1: 0
Ptr2: 0x761740
Test Destruct()

可以看出调用move()后,ptr1被置为nullptr(0), ptr2被设置为0x761740。

常见的陷阱
  • 不要使用指针初始化多个智能指针。

  • 不要delete get()返回的指针。

总结
  1. 智能指针是对象而不是指针。
  2. 智能指针解决的是动态内存管理的问题(堆内存)。
  3. shared_ptr的循环依赖问题通过weak_ptr来解决,weak_ptr不拥有对象的所有权,一个share_ptr可对应多个weak_ptr。
  4. unique_ptr可算作auto_ptr的翻版,不允许多个unique_ptr持有同一个对象。
  5. auto_ptr已经被弃用。
参考地址

C++ 智能指针

c++智能指针

C++智能指针的使用(非常详细)

C++智能指针详解

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/862392.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号