最近读了Accelerated C++,做一下整理笔记
第0章 入门
1. 如果要使用头文件中的人和名字,需要提前#include;
2. return 0表示成功;
第三章 使用批量数据
1. 对于类的对象来说,类自己会说明如果没有指定初始化的值会如何初始化,如string会初始化为空字符串;然而其他的没有显式初始化的内置类型的局部变量是不明确的,可能是变量创建时所占内存刚好含有的值;
2. 输出double类型的精度可以使用setprecision来控制输出的小数位数;
3. 比如vector.size()这种类型的变量,因为不同的系统可能会定义出不同的类型,因此使用标准库定义的size_type来表示容器的大小是一个良好的习惯做法,我们也应该使用它来定义容器的大小;
4. 定义了homework这个vector类型的变量之后,可以使用sort(homework.begin(),homework.end())来对其进行排序;
5.不管什么时候,如果一个表达式中同时出现了普通的整数和无符号类型的整数,普通的整数都会被转换成无符号类型。因此表达式homework.size()-100会生成一个无符号类型的结果,也就是说它永远都不会比0小;
第四章 组织程序和数据
1. 传值调用法,向函数的形参传递实参的数值,形参将会是实参的拷贝;
2. 引用调用法,通过向函数传递引用进行传递,这种做法直接使用实参的数值,不拷贝;另一方面,如果不想改变实参的数值,可以使用const &引用,需要注意的是:
如果我们定义了一个非const类型的引用,就不能让它指向一个常量对象或者常量引用,因为这样做会违反const的意思。
因此不能给非常量引用的形参传递常量引用,但是可以给常量形参传递非常量引用;
3. 如果结构体类型的容器,调用sort,是不知道你进行比较的是结构体中的那个元成员的,因此可以单独实现comare类型的谓词,在谓词中对结构体的成员进行比较,返回比较的结果,这样再对容器进行sort时,第三个变量传入这个谓词,即可实现针对某一成员的比较如:
bool compare(const Student_info& x, const Student_info& y){ return x.name<y.name;} //实现由小到大的排序
sort(students.begin(),students.end(),compare)
4. 当我们在#include 指令中使用一对双引号,而不是尖括号,来把头文件名字包括起来,这样做的意思是,要求编译器把这个头文件的全部内容复制到程序中#include所在的地方;
5. 头文件应当只声明那些必要的名字,通过限定头文件中的名字,我们可以为用户提供最大的灵活性。如果在头文件中写了using std::vector的声明,那么包含头文件的所有程序都会有这样的声明,不管它们是否需要,因此头文件应当使用完整的经过限定的名字,而不是使用using声明;
6. 一个好习惯:作为编译程序的一部分,头文件需要确保多次包含一个头文件是安全的,方法就是在.h的声明的开始和结束处加入#ifndef #endif
7. 在源文件中,使用using声明没有什么问题。
8. 函数名可以重载。只要函数的参数个数或类型不同,同一个函数名function-name就可以定义多个函数,系统可以区分相同类型的引用和常量引用。
第五章 使用序列式容器并分析字符串
1. 迭代器是一个值,它能够
a. 标识一个容器和容器的一个元素
b. 允许检测元素中保存的值;
c. 提供在容器元素之间移动的操作;
d. 使用容器可用有效处理的方式来约束可用的操作;
2. 迭代器,我的理解实际上就是容器中的一个元素的指针。如:vector<Student_info>::const_vector iter = students.begin();
3. 通过对迭代器进行*解引用,如 *iter.name, iter->name可以访问该元素的变量;
4. 可以用过对迭代器进行使用,取代索引;对迭代器的直接++可以指向下一个元素;
5. vector 容器是数组类型的,可以随机索引,缺点是插入和删除很慢,因为需要移动所有的元素;
当从vector中删除一个元素时,指向被删除元素和它之后所有元素的迭代器就都失效了,而push back会使所有的都失效。因为从vector中删除一个元素会移动后面的所有元素,而push back会引起整体vector的重新分配。因此,使用vector类型的begin end,如果调用了push back之类的,需要格外的小心迭代器的失效问题。
list容器是链表类型的,不能随机索引,但是可以随机的插入删除。
由于list不支持随机访问,因此无法使用标准库sort对list进行排序,但是list中有自己的sort成员函数。
第八章 编写反泛型函数
1. 实现泛型函数的语言特性叫做模板函数
template <typename T>
inline T const& Max (T const& a, T const& b)
{
return a < b ? b:a;
}
2. 如果你使用一个依赖于模板参数的类型,如vector<T>,而且你想要使用这个类型的成员时,比如size_type,它本身也是一个类型时,你必须在整个名字之前加上type_name,以便让系统知道要把这个名字当作一个类型来对待。即如:
typedef typename vector<T>::size_type vec_sz;
vec_sz size = v.size();
3. 迭代器:C++标准库中的一个重要贡献是,通过把迭代器用作算法和容器之间的粘合剂,算法可以获得数据结构的独立性,此外,算法使用的迭代器都要求支持某些操作,这样我们就可以根据这些操作来分解算法,这就意味着,我们很容易把一个容器和能够在这个容器上使用的算法匹配起来。
迭代器分为五种: 输入迭代器,输出迭代器,前向迭代器,双向迭代器,随机访问迭代器。
vector和string的迭代器都是随机访问迭代器,因为都可以要求随机访问,list类型是双向的,只能顺序递增递减。