zoukankan      html  css  js  c++  java
  • 《C++ Primer》读书笔记

    第一章 开始

    类型:程序所处理的数据都保存在变量中,而每个变量都有自己的类型

    内置类型:语言自身定义的类型(而形如string等类型都是标准库定义的)

    main的返回值:0表示成功,非0指出错误类型

    从命令行运行编译器

    for语句

    术语表:缓冲区、cerr、clog、表达式

    第一部分 C++基础

    第二章 变量和基本类型

    几种字符类型:char 、wchar_t 、char16_t 、char32_t

    内置类型的机器实现:内置类型如何在内存存放

    将负数转换为无符号类型:结果为无符号数的模加上这个负数

    字面值常量:每个字面值常量都对应一种数据类型、字符串字面值(实际是由常量字符构成的数组),可以指定字面值的类型

    转义序列:回车 、换行

    对象:指一块能存储数据并具有某种类型的内存空间

    初始化:列表初始化、默认初始化

    变量声明和定义的关系:分离式编译、extern

    复合类型:基于其他类型定义的类型

    声明符:声明语句int &r;中,&r为声明符,声明符命名了一个变量,也指定该变量为与基本数据类型(此例为int)有关的某种类型

    引用&引用类型:我们称r为引用或引用类型

    指针:*p为声明符,p是变量名,我们称p为指针或指针变量

    const限定符:常量引用(对常量的引用)、可以将一个常量引用绑定到变量、字面值、表达式(因为不允许通过该引用修改这些对象)

    顶/底层const:执行对象拷贝时的限制

    constexpr:声明常量

    decltype类型指示符:返回表达式的类型

    编写自己的头文件:头文件通常包含那些只能定义一次的实体,如类、const、constexpr变量

    预处理变量:#ifdef、#ifndef、#endif

    术语表:常量表达式、头文件保护符、未定义、void*

    第三章 字符串、向量和数组

    标准库类型string

    string::size_type类型:string的size函数返回的是一个string::size_type类型的值;string类及其他大多数标准库类型都定义了几种配套的类型,体现了标准库类型与机器无关的特性,类型size_type即是其中的一种,通过域操作符来表明名字size_type是在类string中定义的、

    处理string对象中的字符:cctyoe头文件中的函数

    迭代器:使迭代器失效的操作

    数组:数组的引用,数组的下标类型为size_t,数组名和指针

    标准库函数begin和end

    c_str函数:返回一个C风格的字符串,返回结果是一个指针,该指针指向一个以空字符结束的字符数组,指针的类型是const char*

    使用数组初始化vector对象:vector<int> vec(begin(arr), end(arr));

    术语表:直接初始化、值初始化、->运算符

    第四章 表达式

    表达式:最小的计算单元。一个表达式包含一个或多个运算对象,通常还包含一个或多个运算符。表达式求值会产生一个结果。

    字面值和变量是最简单的表达式,其结果就是字面值和变量的值。

    表达式本身也可以作为运算对象。

    左值和右值

    运算符的优先级和结合律

    位运算符:检查和设置二进制位

    类型转换:显示转换(static_cast)

    术语表:复合表达式、整型提升、短路求值

    第五章 语句

    表达式语句:在一个表达式的末尾加上分号

    switch语句:对括号里的表达式求值,然后和各case标签的值比较

    do while语句:先执行后判断;条件为假终止循环

    goto语句:容易引发错误,慎用

    try语句块:throw表达式、catch子句、异常类

    术语表:块、带标签语句、异常声明、terminate

    第六章 函数

    形参名是可选的:无法使用未命名的形参

    局部对象:自动对象、局部静态对象

    引用形参:是对应实参的别名,可避免拷贝

    const形参:p190

    数组引用形参:形参是数组的引用,有限制(大小固定)

    main的形参的使用:处理命令行选项

    可变形参:initializer_list类型的形参、省略符形参

    返回值:初始化调用点的临时量

    引用返回左值:返回引用的函数

    返回花括号包围的值列表

    主函数main的返回值

    返回数组指针使用的类型别名:尾置返回类型、decltype

    重载、内联函数、默认实参

    constexpr函数:返回常量表达式的函数,被隐式地声明为内联函数

    调试帮助:assert、NODEBUG

    函数指针

    术语表:二义性调用、assert、候选函数、可行函数

    第七章 类

    使用类定义自己的数据类型

    this:一个(指向类类型非常量版本的)常量指针,总是指向调用对象

    const成员函数:修改this指针的类型(把this设置为指向常量的指针),故该函数不能改变调用它的对象的内容

    定义/初始化/拷贝/赋值/销毁 类的对象

    构造函数:类控制其对象的初始化过程的方式

    合成的默认构造函数:如果不存在类内的初始值,则默认初始化该成员

    构造函数初始值列表:后执行函数体

    拷贝对象:初始化、传值调用、返回一个对象

    赋值操作:使用了赋值运算符时

    我们不定义上面这些操作(初始化/拷贝/赋值/销毁),编译器将替我们合成它们

    封装性:使用访问说明符,使用户不可访问类的部分成员,public成员定义类的接口,private部分封装了类的实现细节

    友元:访问相关联的类的私有成员,友元类的成员函数也可访问

    成员函数&内联:定义在类内部的成员函数是自动inline的,而在类外定义的成员函数必须用inline关键字修饰

    可变数据成员:mutable关键字声明;即使它是const对象的成员也是可变的

    基于const的重载:对某个对象调用重载成员函数时,将根据该对象是否是const决定调用哪个版本

    不完全类型:前向声明的类(仅声明类),不能定义以不完全类型作为参数或返回类型的函数

    委托构造函数

    explicit:转换构造函数、一步类类型转换

    聚合类、字面值常量类

    类的静态成员:不能在类的内部初始化静态成员,但可以为constexpr的静态成员提供const整型的类内初始值

    术语表:抽象数据类型、显式构造函数、接口、名字查找、=default

    第二部分 C++标准库

    第八章 IO库

    通过一族定义在标准库中的类型来处理IO

    IO类:istream/ostream/iostream、ifstream/ofstream/fstream、istringstream/ostringstream/stringstream

    IO类型间的关系:类型ifstream和istringstream都继承自istream,可将派生类对象当作其基类对象使用

    IO对象无拷贝或赋值:不能拷贝或对IO对象赋值,即形参或返回类型必须是引用类型

    IO库条件状态:可被任何流类使用的一组标志和函数,指出给定流是否可用

    输出缓冲区:保存程序读写的数据,可以管理该缓冲区

    文件输入输出:绑定文件的方式、按指定mode打开文件、关闭关联文件close

    文件模式:类fstream定义的一组标志,在打开文件时指定,用来控制文件如何被使用

    术语表:字符串流、stringstream

    第九章 顺序容器

    类型:vector、deque、list、forward_list、array、string

    array:一种数组类型,其对象大小是固定的

    使用元素类型的默认构造函数:只接受容器大小参数时,类必须要有默认构造函数

    容器操作:类型别名,支持<、<=运算符,所有容器都支持相等运算符

    emplace操作:构造而非拷贝元素

    使迭代器失效的容器操作:p315

    容器适配器:为容器操作定义了不同的接口,来与容器类型适配

    术语表:适配器、左闭合区间

    第十章 泛型算法

    标准库容器定义了很少的操作(添加、删除元素,访问首尾元素等),有更多的操作(如查找特定元素、重排元素等)需要通过算法实现。

    迭代器令算法不依赖于容器,但算法依赖于元素类型的操作

    算法:find、count、accumulate、equal、fill、replace、sort、unique、stable_sort、for_each、transform

    插入迭代器:一种向容器中添加元素的迭代器,back_iterator

    谓词作为参数:谓词是一个可调用的表达式,其返回结果是一个能用作条件的值,如cmp(返回能作为条件的bool值,能调用cmp(a, b))

    标准库算法或使用一元谓词或使用二元谓词,一元谓词意味着该谓词只能接受一个参数

    lambda表达式:当算法要求使用X元谓词,而实际使用到的谓词接受的参数个数大于X时,我们需要使用lambda表达式

    可调用对象:可对其使用调用运算符的对象,如函数、函数指针、lambda表达式、重载了函数调用运算符的类

    bind函数:解决谓词参数数目问题

    插入迭代器:back_inserter、front_inserter、inserter

    iostream迭代器:将对应的流当做一个特定类型的元素序列来处理

    反向迭代器:需要递减运算符

    _copy版本的算法:将元素写到一个指定的输出目的位置

    _if版本的算法:接受一个谓词

    链表类型list和forward_list优先使用成员函数形式的算法:不使用通用算法,因为它们不支持随机访问迭代器

    术语表:istream_iterator、ostream_iterator、迭代器类别

    第十一章 关联容器

    元素按关键字来保存和访问

    类型:map、set、multimap、multiset、及其相应的无需版本(前面加unordered_)

    map:关键字-值对的集合,关联数组

    set:支持高效的关键字查询操作

    pair类型:map中的元素的类型,first成员保存关键字,second成员保存对应的值

    multi:允许多个元素具有相同的关键字

    关联容器不支持顺序容器的位置相关的操作(如push_back等),因为其中的元素是根据关键字存储的

    关键字类型的要求:该类型要求定义了“行为正常”的<运算符

    自定义组织一个容器中元素的操作类型:multiset<Sales_data, decltype(compareIsbn)*> bookstore(&compareIsbn);

    关联容器额外的类型别名:key_type、mapped_type、value_type

    添加元素:insert、emplace

    访问元素:find(k)、count(k)、low_bound(k)、upper_bound(k)、equal_range(k)

    无序容器:组织元素不是通过使用比较运算符,而是使用一个哈希函数和关键字类型的==运算符

    术语表:hash、哈希函数、严格弱序

    第十二章 动态内存

    标准库定义了两个智能指针类型来管理动态分配的对象

    每个程序拥有一个内存池,我们称之为自由空间(或堆),程序用堆来存储动态分配的对象

    动态分配的对象:在程序运行时分配的对象,其生存期由程序来控制

    管理动态内存:new在动态内存中为对象分配空间并返回一个指向该对象的指针(我们可以选择对对象进行初始化);delete接受一个动态对象的指针,销毁该对象并释放与之关联的内存

    使用动态内存易出现的问题:内存泄漏、产生引用非法内存的指针

    为了更容易地使用动态内存,新的标准库提供了两种智能指针类型来管理动态对象

    智能指针:负责自动释放所指向的对象

    shared_ptr类:初始化/赋值、支持的操作

    make_shared函数:创建一个动态对象并初始化,返回指向该动态对象的shared_ptr

    make_shared用其参数来构造给定类型的对象,如调用make_shared<string>时传递的参数必须与string的某个构造函数相匹配

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

    即如果有n个shared_ptr指向同一个对象,那该对象的引用计数就是n,于是每销毁一个shared_ptr时,引用计数就减1

    几种递增/递减引用计数的情况:譬如返回一个智能指针将递增计数,因为在调用点会有一个shared_ptr保存返回来的智能指针

    程序使用动态内存的一个原因:程序需要在多个对象间共享数据

    Blob类:Blob对象的不同拷贝之间共享相同的元素,实现代码

    直接管理内存:new无法为其动态分配的对象命名,值初始化与默认初始化的区别

    new分配的对象都是默认初始化的

    通过内置指针管理的动态对象的生存期:直到被显式释放之前,局部指针变量离开作用域会被销毁

    delete之后重置指针值:防止空悬指针

    shared_ptr与new结合使用:将一个智能指针绑定到一个用new动态分配的内存上,即用new返回的指针来初始化智能指针

    用来初始化智能指针的普通指针:默认是指向动态内存的,如果不是,则必须提供自己的操作来替代delete

    不要混用智能指针和内置指针:智能指针的特性只在智能指针之间操作才会有效

    unique_str类:绑定到一个new返回的指针上,不支持普通的拷贝和赋值操作

    不能拷贝unique_str的例外:可以拷贝和赋值一个将要销毁的unique_ptr

    向unique_ptr传递删除器:默认使用delete释放它指向的对象,可重载一个删除器;类似于重载关联容器的比较操作

    weak_ptr类:不可控制所指向对象生存期的智能指针,指向由一个shared_ptr管理的对象

    StrBlobPtr类:相当于指向StrBlob类的指针,可访问修改vector<string>的元素,实例代码

    动态数组:一次性为很多元素分配内存

    allocator类:允许我们将分配和初始化分离,而new将内存分配和对象构造组合在了一起

    allocator支持的操作:分配/释放内存、构造/销毁对象

    标准库为allocator类定义了两个伴随算法:在分配的原始内存中创建对象

    文本查询程序:标准库相关内容学习的总结

    术语表:释放器、定位new、引用计数

    第三部分 类设计者的工具

    第十三章 拷贝控制

    类对象的几个操作:拷贝、移动、赋值、销毁

    五种特殊函数:拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值函数、析构函数

    通过定义拷贝控制成员:使类的行为看起来像一个值,或像一个指针

    行为像值的类:对于类管理的资源,每个对象都拥有一份自己的拷贝

    行为像指针的类:多个对象共同管理相同的资源

    拷贝并交换:将左侧运算对象与右侧运算对象的一个副本进行交换,而返回左侧对象,常用于定义赋值运算符

    拷贝控制示例:练习应用拷贝控制成员

    动态内存管理类:该类在运行时分配可变大小的内存空间,自己进行内存分配,如标准库中的vector类

    StrVec类:vector类的简化版本,练习如何实现动态内存管理类,主要知识点为allocator类的应用

    对象移动:移动而非拷贝对象,类似IO类、unique_ptr这样的类的对象不能拷贝但可以移动

    右值引用:必须绑定到右值的引用

    标准库move函数:可显式地将一个左值转换为对应的右值引用类型,即可以通过它来获得绑定到左值上的右值引用

    移动构造/赋值函数:直接接管目标对象的资源,而不需要拷贝

    挑选移动还是拷贝函数:根据传递的实参,如实参是右值,当然选移动

    noexcept:声明函数不会抛出异常

    引用限定符:&和&&放在参数列表后面,分别指出this可以指向一个左值(即只能向可修改的左值赋值)或右值

    术语表:拷贝初始化、删除的函数、move、移动迭代器

    第十四章 重载运算符与类型转换

    不可重载的运算符::: 、.* 、. 、?:

    作为成员还是非成员:非成员的可以是算术、相等性、关系和位运算,成员的有=/[]/()/->/+=/++/解引用

    重载输入运算符>>:需要检查读取操作是否成功,即必须处理输入可能失败的情况

    定义前置/后置版本的递增/减运算符:为了区别开来,会使后置版本多一个形式上的整型形参

    函数调用运算符:可以像使用函数一样使用该类的对象,与可调用对象的共性,funtion类型

    类类型转换:类型转换运算符及使用它应避免二义性

    术语表:调用形式、类类型转换、类型转换运算符、函数表、函数对象

    第十五章 面向对象程序设计

    面向对象程序设计基于三个基本概念:数据抽象、继承和动态绑定

    OOP概述:数据抽象(将类的接口与实现分离)、继承(定义相似的类型并对其相似关系建模)、动态绑定(在一定程度上忽略相似类型的区别,而以统一的方式使用它们的对象)

    虚函数:某些成员函数,基类希望它的派生类各自定义适合自身的版本

    动态绑定(函数调用):使用基类的引用或指针调用一个虚函数时发生动态绑定

    派生类可以继承定义在基类中的成员,但是派生类的成员函数不一定有权访问从基类继承而来的成员

    派生类对象的组成:一个含有派生类自己定义的非static成员的子对象 + 一个与该派生类继承的基类对应的子对象(如果由多个基类,此子对象也有多个)

    派生类向基类的类型转换:因为派生类对象中含有与其基类对应的组成部分,所以能把派生类的对象当成基类对象来使用,而我们也能将基类的引用或指针绑定到派生类对象中的基类部分上;编译器会隐式地执行派生类到基类的转换!!但该转换只对指针或引用类型有效

    类型转换带来的:可以把派生类对象或派生类对象的引用用在需要基类引用的地方,同样也可以把派生类对象的指针用在需要基类指针的地方

    派生类不能直接初始化其对象中的基类部分:和其他创建了基类对象的代码一样,必须使用基类的构造函数来初始化它的基类部分

    即每个类控制它自己的成员初始化过程

    派生类的作用域嵌套在基类的作用域之内:派生类成员可以像使用本类成员一样使用基类的成员

    防止继承的发生:在类名之后跟一个关键字final

    静态类型&动态类型

    抽象基类:含有(或未经覆盖直接继承)纯虚函数的类,我们不能创建抽象基类的对象

    派生类访问基类的成员:protected成员的特性

    三种继承方式对于访问控制的影响:派生类对其继承而来的成员的访问权限

    改变个别成员的可访问性:使用using声明来改变派生类继承的某个名字的访问级别

    继承中的名字查找:派生类的作用域嵌套在基类中,对象的静态类型决定了从哪个类开始搜索名字

    名字查找先于类型检查:因为派生类的作用域嵌套在基类中,故其中与基类同名的函数会隐藏基类中的函数,即只要找到此名字的函数就停止向基类搜索

    虚析构函数:动态分配继承体系中的对象,在基类中将析构函数定义成虚函数

    继承与拷贝控制:位于继承体系中的类进行拷贝控制操作时应注意基类的拷贝控制

    继承的构造函数:派生类可使用using声明语句继承基类的构造函数,但不能继承默认、拷贝和移动构造函数

    容器与继承:使用容器存放继承体系中的对象

    文本查询程序再探:扩展文本查询程序,增加更多查询操作,作为继承的最后一个例子

    术语表:可访问的、派生类向基类的类型转换、动态类型、覆盖、多态性、重构、公有继承

    第十六章 模板与泛型编程

    模板是泛型编程的基础

    模板的编写格式:函数/类模板、类模板的友元、成员模板

    模板实参的深入:类型转换、显式实参

    重载与模板:特例化版本优先、非函数模板优先

    引用折叠和右值引用参数:函数参数是右值引用

    可变参数模板:sizeof...运算符、参数包、包扩展

    模板特例化:模板的一个特例化版本,并非重载模板

    术语表:模板参数、模板参数列表、类型参数、实例化、成员模板、参数包、函数参数包、类型转换

    第四部分 高级主题

    第十七章 标准库特殊设施

    介绍四个具有特殊目的的标准库设施,以及IO库中某些不常用的部分

    tuple类型:类似pair,但包含的类型更多

    biset类型:相对位运算来说,处理二进制数更容易

    正则表达式:很好的描述字符序列的方法

    随机数:随机数引擎+分布类型,我们说的随机数发生器就是指分布对象和引擎对象的组合

    IO库再探:一系列操纵符控制输入输出格式、未格式化的输入/输出操作允许将一个流当做一个无解释的字节序列来处理、定位流中位置并随机访问

    术语表:tupe、biset、regex、cmatch、smatch、未格式化IO、随机数引擎、随机数分布、操纵符、种子

    第十八章 用于大型程序的工具

    介绍在设计大型程序时最有用的三个特效,包含异常处理、命名空间和多重继承

    noexcept异常说明:指定某个函数不会抛出异常

    noexcept运算符:可与noexcept说明符混合使用

    异常说明与指针、虚函数和拷贝控制:函数的异常说明对于使用函数的影响

    异常类层次:标准库异常类构成了一套继承体系

    命名空间:作用域 + using声明 + using指示 

    命名空间中的名字&多个文件:using声明的作用域+using指示的弊端

    重载与命名空间:命名空间对函数的匹配过程的影响

    多重继承:从多个直接基类产生派生类

    多重继承的初始化过程及其拷贝控制

    虚继承:每个派生类最多一次继承同一个类

    先初始化虚基类部分,再构造其他非虚基类

    术语表:构造函数顺序、文件中的静态声明、全局命名空间、命名空间污染、重新抛出

    第十九章 特殊工具与技术

    介绍几种用于特定类别问题的特殊工具和技术

    重载new和delete:自定义内存分配的细节

    使用定位new形式构造对象:传递一个地址,在一个特定的、预先分配的内存地址上构造对象,而不分配内存

    运行时类型识别:typeid运算符 + dynamic_cast运算符

    枚举类型:定义新的类型

    类成员指针:数据成员指针 + 成员函数指针

    嵌套类:作用域 + 名字查找 + 与外层类的关系

    union类型:任意时刻只有一个数据成员有值

    局部类:类定义在某个函数内部 + 名字查找

    固有的不可移植的特性:为了支持低层编程而定义的,不可移植的特性是指因机器而异的特性,包括位域、volatile限定符和链接指示

    术语表:匿名union、判别式、RTTI、定位new表达式、枚举类型、dynamic_cast、链接指示

    附录

    静态成员 p268

    析构函数:销毁元素,释放内存

    类型别名:typedef int arrT[10]; arrT是一个由10个整型元素组成的数组的别名

    与类的对象交互必须使用该类的接口

    通过作用域运算符来使用被隐藏的名字

    Sales_data类:p240

    Screen类:p243

    StrBlob类:p405

    StrBlobPtr类:p421

    文本查询程序:p430  T13.42

    Message类:p461

    StrVec类:p465 T13.44

  • 相关阅读:
    定时器
    js中script的上下放置区别 , Dom的增删改创建
    函数声明与应用
    常规选择器
    表格的制作
    流程控制
    For循环
    洛谷P1419寻找段落
    洛谷P1021邮票面值设计
    洛谷P3119草鉴定
  • 原文地址:https://www.cnblogs.com/xzxl/p/7624301.html
Copyright © 2011-2022 走看看