C++复健2(未整理)
conversion function
转换函数
non-explicit-one-argument ctor
1 |
|
编译器会寻找转换函数,不存在,存在多个都会报错
point like classes 仿指针的类
智能指针
我们希望指针能够更加的智能,能做更多的事情,C++11中继而出现了智能指针概念
成员模板中在只能指针也有应用到,为了模拟父类指针能够指向子类
因为在继承关系中,父类的类型确实是可以被子类的值,赋值,就想动物类中可以的值有人,猫,狗各种值一样
需要注意的是 -> 这个符号是可以持续作用的(在重载该符号时,并不会被消耗
容器的对应的迭代器,实际上也可以称为智能指针
其中++ —的遍历操作的实现就是重载运算符函数
function-like classes,仿函数
标准库会继承奇特的base classes
namespace经验谈
不同的测试函数,类,全局变量使用不同的命名空间,作为分隔区
互不干扰
specialization
模板特化(模板泛化的反面)
作用就是特殊的类型如果有需要,再指定特殊的具体讨论
partial 模板的偏特化 (局部特化
- 个数上的偏特化
- 最小类型的指定
- 范围上的偏特化
- 指定范围为指针的类型无论
模板的模板参数,需要注意的是假如模板中有多个模板参数,(定义对象会出现问题,一个坑,编译器无法编译,解决方法不同)
使用的是不是模板模板参数实现的对象,观察的是:调用时,是否所有的模板参数都指定了类型,如果有模糊地带,换句话而言,就是是否还存在你想让编译器来帮你推导的数据类型。
C++标准库
吐槽
侯捷老师强烈建议,使用STL标准库,我个人认为,这种说法是不适合当前的面试的情况的,因为遇到了大部分,需要手撕链表二叉树哈希表等面试题目,平时也在刷leetcode等题库,可以体会到,当前的面试要求是,调用标准库算法,都是人下人(极端的说,不过确实有人说脚本小子,库小子的蔑称传开
在开发的时候当然还是要用标准库,毕竟标准库的算法并不是为面试提供的,而面试之后,你才能加入公司进行开发工作,而你写的手撕代码的实现,在开发中却很可能就完全用不到,调个库几乎就可以完成任务了,所以就会给人一种经典面试造火箭,工作扭螺丝的感觉。
学习标准库
第一步当然是都要调用,知道其用法
常用容器,常用,甚至不常用的算法,至少调用过一次
variadic templates
数量不定的模板参数
c++11中的语言特性
1 |
|
需要注意的是…的位置,不同位置是不同的前后出现次序
随之更新的标准库中有很多都用到了这个新语法(新是相对98而言的),如今c++11距离至今已经11年了,c++20 加入了协程等(稍微了解了一下),和其他很多新特性,但是目前国内c++11居然还是主流(不好说。
c++11的语法糖
auto 实际上就是一个智能的指针
写迭代器的时候懒得写这么长(当然你还是得会写,这是C++程序员的基本素养所在)
用auto可以代替,类型推导都交给auto来处理,偷懒。
需要注意的是,推导的前提是得有值给编译器作为依据。
有些人干脆认为全都用auto好了,那你为啥不直接用PHP捏,写js全写any不就完了呗,开发都是用shell来写,因为shell直接就一种数据类型。(还是那句话:这是C++程序员的基本素养所在
for的新语法
主要是针对容器的遍历
语法模板
1 | for(decl : coll){ |
使用范例
1 | int main() { |
reference
引用
在没有看侯捷老师的课程之前
引用在我的脑子里等同于 指针常量,在编译器中也是将引用当指针来看待
但是实际上,并不是的(尽管作用相同),逻辑上讲,引用相当于别名
别名和原名在调用sizeof函数调用中是一样的大小(这是一种假象,编译器制造出来的)
ps:java中的所有变量都是reference
而指针常量呢?
1 | int x; |
编译器中
1 | int test(const int& num) const{} |
总的来说,能用引用就引用,省事,还快,一般用到参数传递传出的描述。
对象模型
Vptr 和 vtbl
虚指针
虚基表
子类继承父类时
父类出现虚函数,子类一定也会继承得到虚函数
子类中调用虚函数的形式时,
通过的对象的指针p再找到继承的来的虚指针vptr,通过虚指针找到虚基表vtbl,再找表中的第n个虚函数的地址进行调用。
1 | (* p->vptr[n])(p); |
这就是动态绑定
也就是常说的的多态。
只要基础硬得跟石头一样,在进行编程时才会知其然所以然
关于this
对象的函数的调用,在编译器看来
1 |
|
关于const
当成员函数中,const存在和non-const也存在。const 对象只会调用const的函数(防止了二义性的问题
相应的non-const object 只能调用non-const函数
我理解为编译里的读写锁机制
设计一个类,根据需求,实现功能,都要好好考量,每一个成员函数是否需要const修饰
(const就是算签名的一部分)
标准库的string应用的引用计数
总结起来就是八个字:就是读时共享,写时复制
COW ,在fork的进程中的对全局变量的处理也是相同的思想
关于new. delete
内存池中需要考虑到用到
重载delete 和 new和delete[],new[];
由于这两个函数(运算符)其实是全局的函数,把它们当运算符看也没问题,之前有说过了,new实际上是调用的malloc后构造
而delete 是调用析构后再进行free.
一般定义限定在任何一个对象的命名空间中,但是需要static修饰
既然是重载,肯定是有自己的想法的,说明单纯的new和delete已经满足不了
就衍生出了,带参数的new 和 delete
需要注意的是
带参数的new 不一定需要再写对应的delete
当这个带参数的new在执行构造抛出错误时才会调用对应的delete