C++_primer_plus阅读笔记

16 篇文章 2 订阅

第1章 开始

  • 输入运算符(>>)与输出运算符(<<)类似,接受一个istream作为其左侧运算对象,接受一个对象作为其右侧运算对象。输入与输出运算符返回其左侧运算对象作为其计算结果。因此下面两种写法等价.
    cin>>v1>>v2;
    (cin>>v1)>>v2;
  • 成员函数:成员函数是定义为类的一部分的函数(member function),有时也被称为方法(method)。

第2章 变量和基本类型

  • 当赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。当赋给带符号类型一个超出它表示范围的值时,结果是未定义的。(可能正确也可能不正确也可能崩溃)。
  • 如果两个字符串字面值位置紧邻且仅由空格、缩进和换行符分隔,则它们实际上是一个整体。
  • 初始化不等于赋值,赋值是把原来的值擦除以一个新值代替,初始化是创建变量时赋予其一个初始值。
  • 使用extern可以声明一个变量但是不定义它。如:
    extern int i; //声明i而非定义i
    int i ; //声明并定义i
    extern double pi = 3.1416 //定义
  • 作用域:同一个名字在不同的作用域中可能指向不同的实体。名字的有效区域始于名字的声明语句,以声明语句所在的作用域末端为结束。
  • 引用:为对象起了另外一个名字。(引用并非对象,只是为一个已经存在的对象所起的另外一个别名),也不能定义指向引用的指针。
int ival = 1024;
int &refval = ival;	//refval指向ival(是ival的另一个名字)
int &refval2;	//报错:引用必须被初始化,引用初始化以后无法绑定到其他对象上
  • 在定义多个引用和指针时候每个前面都要加&(或*),如:int *a,*b;
  • const int aint const a等价
    const int *aint const * a等价,与int * const a不等价,前者可以指向别处,但是不能改指定的值,后者不可以指向别处,但是可以修改指针指定的值。const int * cosnt a则既不能指向别处,也不能修改指定的值。
  • 对常量引用只能使用引用常量,即
    const int ci = 1024;
    const int &r1 = ci正确
    int &r2 = ci 错误,试图让一个非常量引用指向一个常量对象

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

  • 使用cin读入字符串string时,遇到空白字符就停止了。这时使用getline(cin,s)可以读取一整行。
  • C++语言中的字符串字面值并不是标准库类型string的对象。
  • 对于字符串s,使用for(auto c:s) 要想修改字符串,必须在c前加&(引用)
  • vector<int\>::iterator it; //it能读写vector<int>的元素
    vector<int\>::const_iterator it2; //it2只能读元素,不能写元素
  • int *(&arry)[10] = ptrs //arry是数组的引用,该数组含有10个int指针。
  • 注意:大多数常见的安全问题都源于缓冲区溢出错误。当数组或其他类似数据结构的下标越界并试图访问非法内存区域时,就会产生此类错误。

在这里插入图片描述

第4章 表达式

在这里插入图片描述
在这里插入图片描述

第5章 语句

  • try和throw和catch,将一段可能抛出异常的语句序列放在花括号里构成try语句块。throw表达式语句将控制权转移到相应的catch子句。catch语句负责处理代码抛出的异常。

第6章 函数

  • 函数的返回类型不能是数组。
  • 函数的形式参数使用引用可以避免拷贝,如果函数无须改变引用形参的值,最好将其声明为常量引用。
  • 可以使用非常量初始化一个底层的const对象,但是反过来不行。
  • 函数的返回值类型不能是数组。但可以返回指针数组。
  • int arr[10]; //arr是一个含有10个整数的数组
    int (*p2)[10] = &arr; //p2是一个指针,它指向含有10个整数的数组。
  • 返回指向函数的指针真绕啊。。。。。

第7章 类

  • 定义在类内部的是隐式的inline函数。
  • this是一个常量指针,我们不允许改变this中保存的地址。
  • 引入const成员函数(在类成员函数参数列表之后加 const ),如果不加const ,则我们不能把this绑定到一个常量对象上。即:常量对象以及常量对象的引用或指针都只能调用常量成员函数。
  • 当类中未声明任何构造函数时,编译器才会生成一个默认构造函数。
  • 如果类内包含有内置类型或者复函类型的成员时,则只有当这些成员全都被赋予了类内的初始值时,这个类才适合于使用合成的默认构造函数。
  • 对于struct关键字和class关键字,struct的默认访问权限是privateclass的默认访问权限是public
  • 可变数据成员mutable(mutable data member)永远不会是const,即使它是const对象的成员。
  • 友元关系不具有传递性。
  • 对于一个类sales_data,如果想定义一个使用默认构造函数进行初始化的对象,正确的写法如下:
    sales_data obj; //正确,调用默认构造函数
    sales_data obj() //错误,定义了一个函数而非对象
  • 当在类的外部定义静态成员时,不能重复static关键字,该关键字只出现在类内部的声明语句中。
  • 类的static(静态)成员变量不能在函数内定义(在全局中定义)。

第8章 IO库

此章暂跳

第9章 顺序容器

  • 当将一个容器初始化为另一个容器的拷贝时,两个容器的容器类型和元素类型都必须相同。但是可以用迭代器拷贝不同容器类型的两个容器如下例。
list<string> authors = {"aa","bb","cc"};
deque<string> authlist = (authors.being(),authors.end());
  • array(数组)容器的使用。内置数组不允许拷贝或对象赋值,但array允许。
    在这里插入图片描述
  • 除了array外,swap不对任何元素进行拷贝、删除或插入操作,因此可以保证在常数时间内完成。
vector<int> nums1(10);	//10个元素的vector	
vector<int> nums2(20);	//24个元素的vector
swqp(num1,num2);
  • 除了顺序容器以外,还有3个顺序容器适配器(adaptor):stack、queue、priority_queue。容器、迭代器和函数都有适配器。默认情况下:stack和queue是基于deque实现的。priority_queue是基于vector实现的。

第10章 泛型算法

  • algorithm库的find函数用来查找一个容器中是否具有某个值。如:
vector<int> nums{1,2,3}
find(nums.begin(),nums.end(),2)		//返回迭代器,如果查不到,返回nums.end();
  • accumulate函数(算法)前两个参数是迭代器类型,表示求和的范围,第三个参数类型决定了函数中使用哪个加法运算符以及返回值类型。
  • equal函数(算法),将第一个序列的每一个元素与第二个序列中的元素进行比较,如果相等则返回true,否则返回false。
    equal(rouster1.cbegin(),rouster2.cend(),router2.cbegin()) //router2中的元素数目数目至少与router1一样多。
  • fill写容器的算法,如:fill(vec.begin(),vec.end(),0) //将每个元素重置为0
  • lambda表达式:可以理解为一个未命名的内联函数。具有如下形式:
    [capture list] (parameter list) mutable -> return type{ function body }
    其中:capture list(捕获列表)局部变量列表,通常为空。如果需要改变被捕获的值拷贝(非引用)变量的值,则需要添加mutable。
    可以忽略参数列表和返回类型,但是必选包含捕获列表和函数体。
    如:auto f = [] { return 42; }调用方式:cout<<f()<<endl; //打印42
    如果lambda的函数体包含任何单一return语句之外的内容,且未指定返回类型,则返回void
    捕获列表只用于局部非static变量,lambda可以直接使用局部static变量和它所在函数之外声明的名字。
    指定lambda的返回类型。
    在这里插入图片描述
    因为如果lambda体包含return以外的任何语句,则默认返回void。
    在这里插入图片描述
  • 标准库bind函数:可以修正函数的参数,也可以重新排列其顺序。
  • 反向迭代器的目的是表示元素范围,如果把一个迭代器反向,则连个迭代器指向的不是同一个元素。
    在这里插入图片描述
  • algorithm里有太多函数了,简单过一遍,需要再查看吧。

第11章 关联容器

在这里插入图片描述

  • map和set中的key类型必须可以比较,否则需要自己定义比较函数。
  • 对于map,调用insert返回值是一个pair,pair->first是一个迭代器,pair->second是一个布尔型,false表示已经在map中,什么也不做。对于重复关键字的容器,只返回一个迭代器,因为一定会插入元素。
  • 如果使用无序集合且类型不是内置类型,则需要重载哈希函数和相等判断函数。如果定义了==运算符,则可以只重载哈希函数。

第12章 动态内存

此节暂跳过大多数内容。

  • int *p = new int[0] 创建一个大小为0的静态数组对象是合法的。返回的指针是合法的,但是它并不指向任何元素,因此不能解引用。
  • delete p;//释放一个动态分配的对象
    delete [] pa; //释放一个动态分配的数组

第13章 拷贝控制

  • 拷贝构造函数的参数必须是引用,否则便会造成无限递归(实参传递给形参时,又会调用拷贝构造函数)。
  • 当指向一个对象的引用或指针离开作用域时,析构函数不会执行。
  • 如果一个类需要自定义析构函数,几乎可以肯定它也需要自定义拷贝赋值运算符和拷贝构造函数。

第14章 操作重载与类型转换

  • 相等运算符和不相等运算符应该定义其中一个,然后把另外一个委托给这个定义过的。
  • 14.7后暂跳

第15章 面向对象程序设计

  • 在c++语言中,当我们使用基类的引用(或指针)调用一个虚函数时将发生动态绑定。
  • 对于动态绑定的引用(或指针),当调用虚成员时,会调用对应绑定对象重写的成员。如果不是虚成员,即使重写了,也只调用基类的成员。
  • 在类名后面跟一个final可以防止该类被其他类继承。
  • final说明符与override说明符。(出现在形参列表以及尾置返回类型之后)
  1. override:使用该说明符,当该函数没有覆盖已有的虚函数时(比如参数不一致),编译器将报错。
  2. final:使用该说明符,如果把函数定义为final,则之后任何尝试覆盖该函数的操作都将引发错误。
  • 除了覆盖继承而来的虚函数之外,派生类最好不要重用其他定义在基类中的名字。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值