C++ Primer 读书笔记04

  • 关联容器
  • pair
  • 动态内存
    • 静态内存
    • 栈内存
  • 智能指针
    • shared_ptr
  • 直接管理内存
    • new
    • 空悬指针
    • 智能指针陷阱
  • unique_ptr
  • weak_ptr
  • lock
  • 动态数组
    • 智能指针与动态数组

“C++ Primer”


关联容器

标准库提供 8 个关联容器,他们的不同体现在:

  1. 或者是一个set,或者是一个map
  2. 或者要求不重复的关键字,或者允许重复关键字,允许重复关键字的容器的名字中都包含单词multi
  3. 按顺序保存或者无序保存,不保持关键字按顺序存储的容器的名字都以unordered开头

pair

定义在头文件utility中,pair是一个用来生成特定类型的模板,当创建一个pair时,必须提供两个类型名

pair的数据成员是public的,两个数据成员分别是firstsecond

动态内存

静态内存

静态内存用来保存局部static对象、类static数据成员以及定义在任何函数外的变量,由编译器自动分配和销毁,static对象在使用之前分配, 在程序结束时销毁

栈内存

用来保存定义在函数内的非static对象,由编译器自动分配和销毁,仅在其定义的程序块运行时才存在

智能指针

与常规指针的区别:负责自动释放所指向的对象

shared_ptr
  1. make_shared()函数:最安全的分配和使用动态内存的方法
shared_ptr<int> p3 = make_shared<int>(42);  // 指向一个值为 42 的 int 的 shared_ptr
  1. shared_ptr的拷贝和赋值

    每个shared_ptr都有一个关联的计数器,称为引用计数,无论何时我们拷贝一个shared_ptr,计数器都会递增,如用一个shared_ptr初始化另一个shared_ptr,或将它作为参数传递给一个函数以及作为函数的返回值;当给shared_ptr赋一个新值或是shared_ptr被销毁,计数器递减

    一旦一个shared_ptr的计数器变为 0 ,它就会自动释放自己管理的对象

    shared_ptr的析构函数会递减它所指的对象的引用计数,如果引用计数变为0,shared_ptr的析构函数就会销毁对象,并释放内存

直接管理内存

new

默认情况下,动态分配的对象是默认初始化的,内置类型或组合类型的对象的值是未定义的,类类型对象将使用默认构造函数进行初始化

int *pi = new int;  // pi 指向一个动态分配的,为初始化的无名对象
int *pi2 = new int();  // 值初始化为 0,*pi2 为0
string *ps = new string;   // 初始化为空的 string

值初始化的内置类型对象有着良好定义的值,而默认初始化的对象的值则是未定义的

空悬指针

指向一块曾经保存数据对象但现在已经无效的内存的指针

智能指针陷阱
  1. 不使用相同的内置指针值初始化(或 reset)多个智能指针
  2. delete get()返回的指针
  3. 不使用get()初始化或reset另一个智能指针
  4. 如果使用get()返回的指针,记住当最后一个对应的智能指针销毁后,你的指针就变为无效了
  5. 如果使用智能指针管理的资源不是new分配的内存,记住给它传递一个删除器

unique_ptr

一个unique_ptr拥有它所指向的对象,与shared_ptr不同,某个时刻只能有一个shared_ptr指向一个给定对象,也没有make_shared这样的标准库函数,当定义一个unique_ptr时,需要将其绑定到一个new返回的指针上,初始化unique_ptr必须采用直接初始化形式

unique_ptr<double> pl;
unique_ptr<int> p2(new int(42));
unique_ptr<string> p3(new string("test"));
unique_ptr<string> p4(p3);    // 错误,unique_ptr 不支持拷贝
unique_ptr<string> p5;
p5 = p3;   // 错误,unique_ptr 不支持赋值unique_ptr<string> p6(p3.release()); // 将所有权从 p3 转移给 p6, release 将 p3 置为空
unique_ptr<string> p7(new string("test"));
p4.reset(p7.release()); // 将所有权从 p7 转移给 p4, release 将 p3 置为空,并返回指针,p4 释放原来指向的内存

release()会切断unique_ptr和它原来管理的对象间的联系,如果不使用另一个智能指针保存release()返回的指针,我们就要负责资源的释放

p2.release();    // 错误, p2 不会释放内存,而且我们丢失了指针
auto p = p2.release(); // 正确,但必须记得 delete(p)

不能拷贝unique_ptr规则例外:我们可以拷贝或赋值一个将要被销毁的unique_ptr

unique_ptr<int> clone(int p) {return unique_ptr<int>(new int (p));
}

weak_ptr

weak_ptr是一种不控制所指向对象生存周期的智能指针,它指向由一个shared_ptr管理的对象,将一个weak_ptr绑定到shared_ptr不会改变shared_ptr的引用计数

由于对象可能不存在,不能直接使用weak_ptr访问对象,必须调用lock

lock

此函数检查weak_ptr指向的对象是否存在,如果存在,返回一个指向共享对象的shared_ptr

动态数组

  1. new和数组

    int *pia = new int[get_size()]; // 方括号中必须是整型但不必是常量
    

    new返回的是一个元素类型的指针,分配的内存并不是一个数组类型,因此不能对动态数组调用beginend,也不能使用范围for语句

    智能指针与动态数组

    标准库提供了一个可以管理new分配的数组的unique_ptr版本,使用时需要在对象类型后加上一对空方括号

    unique_ptr<int[]> up(new int[10]); // up 指向一个包含 10 个为初始化 int 的数组
    
  2. allocator

    new将内存分配和对象构造组合在了一起,标准库allocator类定义在头文件memory中,它帮助我们将在内存分配和对象构造分离开来,它分配的内存是原始的、未构造的

    allocator<string> alloc; // 可以分配 string 的 allocator 对象
    auto const p = alloc.allocate(n);  // 分配 n 个未初始化的 string
    auto q = p;    // q 指向最后构造的元素之后的位置
    alloc.construct(q++); // *q 为空字符串
    alloc.construct(q++, 10, 'c');  // *q 为 ccccccccccwhile(q != p)alloc.destroy(--q); // 释放构造的 stringalloc.deallocate(p, n);  // 释放内存
    

C++ Primer 读书笔记04相关推荐

  1. 《计算之魂》读书笔记 04

    <计算之魂>读书笔记 04 1.4 关于排序的讨论 [1.4.3]针对特殊情况,我们是否还有更好的答案? [附录]为什么排序算法的复杂度不可能小于 O(nlogn)O(nlogn)O(nl ...

  2. 推荐系统实践读书笔记-04利用用户标签数据

    推荐系统实践读书笔记-04利用用户标签数据 推荐系统的目的是联系用户的兴趣和物品,这种联系需要依赖不同的媒介.GroupLens在一篇文章中表示目前流行的推荐系统基本上通过3种方式联系用户兴趣和物品. ...

  3. C++ Primer 读书笔记及知识点延伸 chapter2

    C++ Primer 读书笔记及知识点延伸 chapter2 wchar_t宽字符,char16_t  char32_t Unicode字符 ,long long C++11新增加 符号类型前面加上u ...

  4. C++ Primer读书笔记(从后向前看)

    (从后向前看) 标题:重载函数再论 重载函数是C++提出来的概念,但是在C中却未必没有.比如"1+3"和"1.0+3.0",虽然都是加法,做的却不是同的操作:编 ...

  5. c++primer读书笔记

    c++全局变量无声明.多次定义会冲突.利用命名空间 c++四种cast操作符的区别 1.static_cast,支持子类指针到父类指针的转换,并根据实际情况调整指针的值,反过来也支持,但会给出编译警告 ...

  6. C++ Primer读书笔记

    (从后向前看) 标题:重载函数再论 重载函数是C++提出来的概念,但是在C中却未必没有.比如"1+3"和"1.0+3.0",虽然都是加法,做的却不是同的操作:编 ...

  7. 【C++ Primer读书笔记】第1章 - 开始

    读书笔记,后续会不断补充修改,欢迎交流.

  8. C++ Primer 读书笔记 (1)

    我的<C++ Primer>扉页记着购书的日期和地点:C++ Primer 2009.11.28购于西区求索.那时对于这本厚书一直心怀敬畏,仿佛是眼前的一座大山.那时,虽然已经大四,但是对 ...

  9. C++入门复习指南,C++Primer读书笔记

    1.碎碎念 因为高中的缘故差不多一年多没写代码了,最近备考CCPC,发现很多东西都忘记了,所以简要复习一下. 我的C++启蒙来自C Primer PLUS,具体记不清了,大概五六年前甚至更早吧,那时候 ...

最新文章

  1. mybatis-plus对datetime返回去掉.0_华为AI认证-TensorFlow2.0编程基础
  2. 使用java调用fastDFS客户端进行静态资源文件上传
  3. bzoj2424 订货
  4. 分布式数据库数据一致性的原理、与技术实现方案
  5. 在每个运行中运行多个查询_Spring Data JPA的运行原理及几种查询方式
  6. win10 设置游戏全屏
  7. Java高级语法笔记-匿名类(Anonymous Class)
  8. Elasticsearch整理笔记(二)
  9. 分布式存储 CentOS6.5虚拟机环境搭建FastDFS-5.0.5集群
  10. 了解java虚拟机---JVM的基本结构(1)
  11. django mysql 修改密码_Django更改sqlite数据库使用mysql数据库 - 李金龙
  12. MSSQL、MySQL 数据库删除大批量千万级百万级数据的优化
  13. 玉米社:短视频运营主要做哪些工作?
  14. 嵌套在iframe页面打印去掉页眉页尾
  15. 面对众多的在线打印平台该怎么选择?
  16. DDSM 数据集格式转换 LJPEG to PNG
  17. grep查找的内容输出到文件
  18. mysql定时任务,每天凌晨1点执行
  19. devc++不兼容_最好的兼容HomeKit的智能灯泡
  20. 李宏毅线性代数笔记7 子空间

热门文章

  1. 恒星日和太阳日【转载】
  2. 【笔记】识别手写数字神经网络
  3. 加速PG中vacuum
  4. python csv 大文件_python 快速把超大txt文件转存为csv的实例
  5. linux编译符号那些事儿
  6. 九龙证券|二股东迎大变革,这只零售股连收4板
  7. 服务器被入侵,执行了2个非常危险的命令
  8. 《伟大的小细节:互联网产品设计中的微创新思维》——3.4 身份特征与使用习惯因素...
  9. 解决 rsync: failed to connect to xxx.xxx.xxx.85 (xxx.xxx.xxx.85): No route to host (113) 问题
  10. 我的世界杯 - 诸神黄昏之战