C++ Primer Plus笔记
C++ Primer Plus笔记
第十章:对象和类
类和结构(class和struct)的区别:结构的默认访问类型是public,而类的默认访问类型是private。
所创建的每个新对象都有自己的存储空间,用于存储其内部变量和类成员;但同一个类的所有对象共享同一组类方法,即每种方法只有一个副本。
内联函数
内联函数是C++为提高程序运行速度所做的改进,常规函数和内联函数之间的主要区别不在于编写方式,而是编译方式。常规函数调用的时候需要执行函数调用操作(参数入栈,设置返回点,跳转到函数入口等),而内联函数在编译的时候直接在调用处展开函数代码,在执行的时候并没有进行函数调用。
因此,多次调用同一个内联函数的时候,编译器会在内联函数被调用处展开多个函数实例,和常规函数调用相比占用更多的内存空间。
内联函数适用于函数调用开销比函数执行开销还要大的场合,内联函数不能递归。
与宏的区别:宏只是字符串替换,没有函数传递的性质,内联函数也是函数,可以传递参数。
其定义位于类声明中的函数都将自动成为内联函数(下边的set_tot
函数)
|
|
也可以在类声明外定义内联函数
构造函数
C++提供了两种使用构造函数来初始化对象的形式,第一种是显式的调用构造函数:
另外一种是隐式的调用:
|
|
此外还有默认构造函数和拷贝构造函数
默认构造函数:未提供显式初始值时,下边是使用默认构造函数的三种形式。
当且仅当没有定义任何构造函数的时候,编译器才会提供默认构造函数;为类定义了构造函数后就必须为它提供默认构造函数。如果定义了非默认参数的构造函数,而没用定义默认构造函数则上边的声明会报错。
默认构造函数可以通过两种方式定义:直接定义一个不接收参数的构造函数;定义提供默认参数的构造函数。
拷贝构造:也叫复制构造,用于将一个对象复制到新创建的对象中。下边四种方式都是拷贝构造。每当程序生成了对象副本时,编译器都将使用拷贝构造函数。编译器生成临时对象时,也将使用拷贝构造函数。
const成员函数
第二行的land.show()
编译的时候会出错,因为show()
方法可能会更改land
对象的属性,而land
对象又被const
所修饰。正确的做法是,在声明和定义show()
方法的时候将其定义为const
成员函数,像下边这样。
对象数组
初始化对象数组的方案是,首先使用默认构造函数创建数组元素,然后花括号中的构造函数将创建临时对象,然后将临时对象的内容复制到相应的元素中。因此,要创建对象数组,则这个类必须有默认构造函数。
第十一章:使用类
运算符重载
语法格式:operatorp(argument-list)
其中最后一个p
表示要重载的运算符,比如operator+(Time)
函数重载:函数重载的关键是函数的参数列表—也称为函数特征标(function signature)。如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则他们的特征标相同,而变量名是无关紧要的。函数名相同而特征标不同的函数是重载函数。
double func(int a, double b) 和 double func(double a, int b)也是重载函数,后边有实验证明。
运算符重载的时候左侧的操作数应该是调用对象,比如A = B*2.75
等价于A = B.operator*(2.75)
。而A = 2.75*B
会出错。
要实现A = 2.75*B
可以通过友元函数来实现。
这样再调用A = 2.75*B;
就等价于A = operator*(2.75, B);
关于函数重载和左值是调用对象做了一个实验。
|
|
上边程序的输出如下,符合预期。
$ ./a.out
fir i
3.3
fir dou
3.3
但是把第二个func函数的定义注释掉之后,使用clang编译的时候会出现./test.cpp:19:18: warning: implicit conversion from 'double' to 'int' changes value from 2.3 to 2 [-Wliteral-conversion] std::cout<<func(2.3, 1)<<std::endl;
的警告。运行的时候会输出
由此证明前边说的,参数列表中参数的顺序不同代表的是不同的函数。
类的自动转换和强制类型转换
第十二章:类和动态内存分配
静态类成员函数
使用static
关键字将类成员函数声明为静态的。
声明为静态的类成员函数不能通过对象调用,也不能使用this指针。因为静态成员函数不与特定的对象相关联,因此只能使用静态数据成员。可以直接使用类名::函数名()
调用,静态类数据成员的使用:类名::变量名
。
C++ Primer
第九章:顺序容器(sequential-container)
顺序容器是按照他们在容器中的位置来顺序保存和访问的
顺序容器
- vector : 可变大小数组,支持快速随机访问,在尾部之外的位置插入或者删除元素可能会很慢。
- deque:双端队列
- list : 双向链表,只支持双向顺序访问
- forward_list:单向链表,只支持单向顺序访问
- array:固定大小数组,支持快速随机访问,不能添加或者删除元素
- string:与vector相似的容器,但专门用于保存字符,随机访问快。
array和forward是C++新标准增加的类型
额外三个顺序容器适配器
- stack
- queue
- Priority_queue
适配器(adaptor)是标准库中的一个通用概念。容器、迭代器和函数都有适配器。本质上,一个适配器是一种机制,能使某种事物的行为看起来像另外一种事物一样。一个容器能接受一种已有的容器类型,使其行为看起来像另外一种不同的类型。例如stack适配器使用一种顺序容器,使其操作起来像一个stack一样。每个适配器都在其底层顺序容器类型之上定义了一个新的接口。
第十一章:关联容器(associative-container)
关联容器中的元素是按照关键字来保存和访问的
主要有两个
map: 元素是key-value对
set:每个元素只包含一个关键字,支持高效的关键字查询操作:检查一个给定的关键字是否在set中
共有八中形式
map : 关联数组:保存关键字-值对
set : 关键字即值,即只保存关键字的容器
multimap : 关键字可以出现多次的 关键字-值 对
multiset : 关键字可以重复出现多次的set
以下四个是无序的集合
unordered_map : 用哈希函数组织的map
unordered_set : 用哈希函数组织的set
unordered_multimap : 哈希函数组织的map,且关键字可以重复出现多次
unordered_multiset : 哈希函数组织的set, 且关键字可以重复出现多次
map和multimap定义在头文件map中
set和multiset定义在头文件set中
无序容器定义在unordered_map和unordered_set中。
使用关联容器的一个例子
|
|
侯婕-STL标准库和泛型编程
STL的六大部件:
- 容器(Containers)
- 分配器 (Allocators)
- 算法 (Algorithms)
- 迭代器 (Adapters)
- 仿函式 (Functors)

下边一个程序用了六大组件。
|
|