IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 智能指针与STL查漏补缺(2) -> 正文阅读

[C++知识库]智能指针与STL查漏补缺(2)

一、CPP11最常用的智能指针shared_ptr

学习参考:https://zh.cppreference.com/w/cpp/memory/shared_ptr

1、shared_ptr的设计思路

(1)auto_ptr和unique_ptr是独占式智能指针,即任何时候智能指针和对象是1对1绑定的,不能2对1

(2)shared_ptr是基于引用计数式的设计,因此可以多个智能指针绑定1个对象(普通指针就是这样的,可以多个指针指向一个对象),这会带来很多方便

(3)shared_ptr在基础的定义和使用方式上,与前2个很类似,所以很容易学会使用

2、shared_ptr的基本使用

在这里插入图片描述
(1)智能指针的创建,一般有2种方式:使用构造函数、使用std::make_shared方法

(2)代码实战:shared_ptr与单个对象的绑定和使用,测试智能指针的多种常见用途

#include <iostream>
#include <memory>

using namespace std;

struct Foo
{
    Foo(){cout << "Foo()" << endl;};
    ~Foo(){cout << "~Foo()" << endl;};
};

struct D
{
    void operator()(Foo* p) const
    {
        cout << "Call  delete from function object..." << endl;
        delete p;
    }
};

int main(int argc, char *argv[])
{
    {
        cout << "constructor with no managed object" << endl;
        shared_ptr<Foo> sh1;
    }

    {
        cout << "constructor with object" << endl;
        shared_ptr<Foo> sh2(new Foo);
        shared_ptr<Foo> sh3(sh2);
        cout << sh2.use_count() << endl;
        cout << sh3.use_count() << endl;
    }

    {
        cout << "constructor with object and deleter" << endl;
        shared_ptr<Foo> sh4(new Foo, D());
        shared_ptr<Foo> sh5(new Foo,[](auto p){cout << "Call delete from lamba" << endl; delete p;});
    }

    return 0;
}

二、shared_ptr的引用计数详解

1、引用计数的获取和检测

(1)use_count
(2)unique
(3)operator bool
(4)reset
在这里插入图片描述

#include <iostream>
#include <memory>
#include <type_traits>

using namespace std;

class C
{
public:
    C(){};
    C(int i):i(i){};
    int i;
};

int main(int argc, char *argv[])
{
    auto sp = make_shared<C>();
    static_assert(is_same<decltype(sp), shared_ptr<C>>::value, "false");//静态断言,编译时起作用
    cout << sp.unique() << endl;
    cout << sp.use_count() << endl;

    return 0;
}

2、引用计数实现智能指针的总结

(1)基本原理仍然是释放智能指针对象时,调用其Deleter,再调用被绑定对象的析构来释放

(2)auto_ptr和unique_ptr都被实现为独占式,所以在=时必然发生占有权转移

(3)shared_ptr增加引用计数,好处是可以让多个智能指针对象,同时绑定一个被管理对象,本质上其实是避免了被管理对象被多次自动释放带来的错误,所以比unique_ptr更好用

3、shared_ptr的其他细节

(1)static_pointer_cast(静态类型强制转换)/dynamic_pointer_cast(动态强制类型转换)

参考学习:https://zh.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast

(2)特化的原子操作(期望对复杂的结构进行无锁操作,而不用担心GC (垃圾回收机制)/内存泄漏)

#include <iostream>
#include <memory>
 
struct BaseClass {};
 
struct DerivedClass : BaseClass
{
    void f() const
    {
        std::cout << "Hello World!\n";
    }
    ~DerivedClass(){ // 注意:它不是虚的
        std::cout << "~DerivedClass\n";
    }
};
 
int main()
{
    std::shared_ptr<BaseClass> ptr_to_base(std::make_shared<DerivedClass>());
 
    // ptr_to_base->f(); // 错误不会编译: BaseClass 无名为 'f' 的成员
 
    std::static_pointer_cast<DerivedClass>(ptr_to_base)->f(); // OK
    // (构造临时 shared_ptr ,然后调用 operator-> )
 
    static_cast<DerivedClass*>(ptr_to_base.get())->f(); // 亦 OK
    // (直接转型,不构造临时 shared_ptr )
}

输出:
Hello World!
Hello World!
~DerivedClass

三、weak_ptr与shared_ptr的关联和使用

参考学习:
https://blog.csdn.net/albertsh/article/details/82286999(必看)
https://zh.cppreference.com/w/cpp/memory/weak_ptr

四、迭代器适配器

参考学习:
http://c.biancheng.net/view/7255.html
https://zh.cppreference.com/w/cpp/iterator
在这里插入图片描述

五、function封装器和可变参数模版

1、function封装器

参考学习:https://blog.csdn.net/gongjianbo1992/article/details/105160627/

2、可变参数模版

参考学习:https://blog.csdn.net/xiaohu2022/article/details/69076281

3、C++系列文章前3部分总结

(1)C++课程前3部分(从C到C++,C++和面向对象,STL和泛型编程)是主体,后2部分是扩展。

(2)前3部分学完,即可使用C++去做事,譬如GUI的qt、譬如AI的opencv

(3)后2部分是C++编程功底和优化、更深度理解C++的,建议有一定C++使用体验后再去学

(4)博客文章更新上也会先暂停C++去更新一些其他东西(海思专题、设备树、python视觉方面相关的),后面再找时间来继续学习并更新,其实大家有了前面的基础,完全可以尝试自己去啃那个C++手册来自学了,已经有能力去看懂和分析上面的东西了!

注:本文章参考了《朱老师物联网大讲堂》课程笔记,并结合了自己的实际开发经历以及网上他人的技术文章,综合整理得到。如有侵权,联系删除!水平有限,欢迎各位在评论区交流。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-04 10:51:31  更:2022-02-04 10:52:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:51:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码