C++ Primer读书笔记梳理系列(二)

本文是《C++ Primer》读书笔记梳理系列(二),涵盖顺序容器、泛型算法和动态内存内容。介绍了vector对象增长方式、string构造与操作,阐述lambda表达式定义、捕获方式,还讲解了动态内存存储位置、智能指针种类及allocator类处理动态数组的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ Primer读书笔记梳理系列(二)

第八章 顺序容器

vector对象如何增长的

  1. 做法
    1. 将已有的元素移动到新空间中
    2. 然后添加新元素
    3. 释放旧的存储空间,一般新空间是旧空间的两倍(有的编译器是1.5倍)
  2. 注意reserve(内存空间),resize(元素个数)的区别
  3. 注意capacity和size的区别

string

  1. 构造方法

    string(cp, n)s是cp指向的数组中前n个字符的拷贝(此数组至少包含n个字符)
    string s(s2, pos2)s是string s2从下标pos2开始的字符的拷贝(若pos2>s2.size(),此函数行为未定义)
    string s(s2, pos2, len2)s是string s2从下标pos2开始的len2个字符的拷贝(若pos2>s2.size(),函数行为未定义;若len2太大,只拷贝剩余元素)
    1. const char*创建string时,指针指向的数组必须以空字符结尾,拷贝操作遇到空字符停止
    const char *cp = "Hello World!!!" //以空字符结束的数组
    string s1(cp); //拷贝cp直到遇到空字符;s1 = "Hello World!!!"
    
    1. 如果传递给构造函数一个计数值,数组就不需要以空字符结尾

      char a[] = {'H', 'i'}; //不是以空字符结尾
      string s2(a, 2); //虽然a不是以空字符结尾,但因为构造函数给了计数值,所以可以
      
    2. 如果我们未传递计数值且数组也未以空字符结尾,或给定的计数值大于数组大小,则是非法的

      string s3(a); //非法
      string s4(cp, 100); //非法
      
  2. 截取字符串substr

  3. string操作

    函数含义
    s.find(args)查找s中args第一次出现的位置
    s.rfind(args)查找s中args最后一次出现的位置
    s.find_first_of(args)查找s中args中任意一个字符第一次出现的位置
    s.find_last_of(args)查找s中args中任意一个字符最后一次出现的位置
    s.find_first_not_of(args)查找s中第一个不在args中的字符
    s.find_last_not_of(args)查找s中最后一个不在args中的字符
  4. 数值转换

    1. to_string()
    2. stod(s)//string->double

第十章 泛型算法

lambda

  1. 定义,表达式表示一个可调用的代码单元,我们可以理解为未命名的内联函数

  2. 形式:[capture list] (parameter list) -> return type {function body}

    捕获列表是lambda表达式所在函数中定义的局部变量

  3. lambda表达式不能有默认参数

  4. 捕获方式

    1. 值捕获,前提是变量可以被拷贝
    2. 引用捕获,前提是捕获该变量是存在的(可不可以修改取决于绑定的那个变量是不是const)
    3. 隐式捕获
  5. 指定lambda返回类型

    1. 默认情况下,如果一个lambbda 函数体包含return之外的任何语句,则编译器假定此lambda返回viod;

第十二章 动态内存

不同方式定义的类型变量在内存中的存储位置是不同的

  1. 静态内存:保存局部static对象、类static数据成员、定义在任何函数之外的变量
  2. 栈内存:保存定义在函数内的非static对象
  3. 堆:存储动态分配的对象,当动态对象不再使用时,我们必须显式地销毁它们。

动态内存与智能指针

  1. 种类

    1. share_ptr允许多个指针指向同一个对象
    2. unique_ptr独占所指向的对象,不支持拷贝与赋值(一个即将被销毁的unique_ptr除外),但是可以调用一些函数将所有权从一个unique_ptr(非const)转移给另一个unique_ptr。
    3. weak_ptr,弱引用,指向share_ptr所管理的对象,但是不改变引用计数
  2. 智能指针的构造函数是explcit

    shared_ptr p1(new int(24)); //我们知道这样是对的,直接初始化
    shared_ptr p2 = new int(24); //那这样呢?错了
    
  3. 不要混合使用普通指针和智能指针

  4. 不要使用get初始化另一个智能指针或为智能指针赋值

动态数组

​ 这里主要介绍一下alloctor类

  1. new的局限性

    1. 它将内存分配和对象构造放在一起
    2. delete将对象的析构和内存的释放放在一起
  2. 先分配大内存,真正需要时才执行对象的创建操作,使用allocator

  3. allocator分配未构造的内存

    auto q = p; //q指向最后构造的元素之后的位置
    alloc.construct(q++); //*q为空字符串
    alloc.construct(q++, 10, 'c'); //*q为cccccccccc
    alloc.construct(q++, "hi"); //*q为hi
    cout << *q << endl; //不行,q指向未构造的内存!
    
    //我们来销毁刚刚构造的对象
    while(q != p)
    {
        alloc.destroy(--q); //这个--符号的位置和上面++符号的位置要注意啊
    }
    
    //当元素被销毁后,我们就可以重新使用这部分内存来保存其他string,也可以将其归还给系统
    alloc.deallocate(p, n); //这里我们归还给系统了
    
  4. 拷贝和填充未初始化内存的算法

    vector<int> vi = {0, 1, 2};
    allocator<int> alloc;
    auto p = alloc.allocate(vi.szie()*2); //分配两倍动态内存空间
    auto q = uninitialized_copy(vi.begin(), vi.end(), p); //拷贝vi到堆区
    uninitialized_fill_n(q, vi.size(), 24); //剩余元素初始化为24
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值