目录
本文也是c++的基础,里面的图片是侯先生的ppt,作为c++基础来说侯先生的ppt做的很详细。若侵权,删立决。
vptr和vtbl
C类继承B类,B类继承A类,还有他们各自在内存中的布局和虚函数表如下图:
注:图中的箭头都代表指针。vptr成为指向虚表vtbl的虚指针。
this
是一根指针,指向函数调用者这个对象,下图中this指向myDoc这个子类对象(在继承体系中一般会指向子类对象)。
Dynamic Binding
下图是静态绑定:(其中有强制转换)
下图中蓝色的代码是动态绑定,图中右侧汇编码124行以上的部分可以转换成c语言调用的形式,也在图中右侧有标出,其中的p就是new B这个指针,指向B这个对象,p->vptr是B这个对象的虚表,n是已经确定vfunc1这个函数的偏移,那么124行以上汇编码执行的是去调用B这个对象的vfunc1函数,并把指向自己的指针传递进去。
const
下图的表中可以看到const修饰的object是不能调用这个object的non-const的成员函数:
转换函数(conversion function)
创建转换函数的规则:1.转换函数必须是类的成员函数;2.转换函数不能指定返回类型,但有返回值;3.转换函数没有参数。
non-explicit
与转换函数方向(1)相反的一个例子:((1)注:转换函数是把自己转换成其他类型,而构造转换函数是把其他类型转换成自己这种类型,如下图找中编译器会把4转换成Fraction类型),下图中的歧义可能有:1.4转成Fracton然后和f相加,2.f转成double然后和4相加之和再转成Fraction。
而下图中的例子编译器在执行f+4时发现了多余一个的编译方式,会产生歧义,所以要借助explicit关键字来明确告诉编译器不使用该成员,从而消除歧义。例如下下图中的explicit修饰的构造转换函数。
下图就是使用关键字后,消除歧义,却带来转换的Error。
Pointer-like class
重载了*和->这2个和指针有关的运算符,从而让该类使用起来像指针。例如下图中共享指针类(使用起来像指针的类)调用Foo类的方法。
STL中的迭代器(iterator)也是Pointer-like class,其中*操作符就是取出iterator当前指向的元素对象,->操作符返回指向当前元素对象的指针。
仿函数(function-like class)
何为仿函数,可以初识下图:
标准库中的仿函数:
标准库中的仿函数的基类:
成员模板
如下图:
模板特化
初识如下:(下图指定了模板参数就是模板特化,不指定参数的模板就是泛化)
模板偏特化,模板参数多余一个,而我们指定了其中一个或多个,就是偏特化,如果模板参数全部被指定了,那就是全特化。如下图,我们来看一个偏特化,是指范围上的偏特化,如下图的指针类型范围。
模板的模板参数
模板参数中typename关键字只有在模板参数中出现时可以与class互相替代,其他地方则不可以。
图释:打小红叉的原因是list这个模板有2个模板参数,它有第二个模板参数有默认值指定,而你模板的模板参数只有一个。
再看一个例子:
再来看一个像模板的模板参数的例子:
可变参数
图释:最后一次没有参数可解开,那么就调用无参的print();sizeof…(args)可以获取这一包参数args的个数。当然可变参数还可以用在函数参数上,且也有标准的取参方式,这个可以参考我的上几期博文。
你的打赏是我奋笔疾书的动力!
支付宝打赏:
微信打赏: