博览网/boolan-C++面向对象高级编程(下)-第2周笔记题

2017-08-17  本文已影响0人  derivator

1.vptr(虚指针)vtbl(虚表)

a.只要类中有虚函数(不论多少个),这个类的实际大小会比类中所有的数据大小相加还要多4,这是因为类中存在虚指针(vptr),同时,虚指针将会指向一个虚表(vtbl),虚表可以被理解成一个数组,其作用是虚函数表的作用是保存类中的虚函数的地址。

b.如上图所示虚函数的调用过程:

取出vptr即得到虚函数表的地址->在虚表中找到对应虚函数地址->通过得到的地址调用函数。

事例:上图中,对象a与b均有虚函数vfunc2(),但是a与b中的vptr不同,它们对应的vtbl就不同(对象a对应A:: vfunc2(),对象b对应B:: vfunc2()),相应的,它们的vtbl中所对应的虚函数地址也不同。

c.动态绑定:

当满足以下三个条件时,编译器会进行动态绑定:

1.通过指针调用函数;

2.指针要做向上转型动作;

3.指针调用的是虚函数。

2.关于this

a.通过对象调用函数时,那个对象的地址就是this

b.this是一根指针,this所指向的对象叫做this对象;

c.C++中,所有的成员函数都有一个隐藏的this pointer参数。

tips:

this在成员函数的开始前构造,在成员函数的结束后清除。

由于this并不是一个常规变量,所以不能取得this的地址。

3.关于const

修饰常量,用const修饰的变量是不可变的。

当const的位置在函数的参数列表(即小括号)后面,且在函数体(即花括号)前面时(用来修饰成员函数),表示这个函数不改变class中的数据。一般的全局函数是不能用const来修饰函数体的

图中红框列成表为:

当成员函数的const与非const版本同时存在时:

4.关于NewDelete

New的动作:

a)分配内存——编译器调用operator new(n)函数(C++),实际调用的是malloc(n)函数(c语言);

b)转型;

c)调用构造函数(ctor)

delete的动作:

a)先调用析构函数(dtor);

b)释放内存——调用delete(n)函数(C++),其实调用的是free(n)(C语言)

5.Operator newOperator delete

a.对全局函数::operator new和::operator delete进行重载(::表示这是全局的),在使用时,编译器先检查是否有对::operator new和::operator delete进行重载,如果有,则调用重载的,否则调用默认的。对::operator new和::operator delete进行重载是一件危险的事情,因为这样会导致所有的new与delete都将使用你所定义的,这会导致分配空间不确定。

b.也可以在class中进行member operator new/delete,这样做只针对这个类使用自定义的内存管理:

c.强制使用全局的new与delete:

Tips:使用newdelete,编译器会首先寻找类内是否有重新定义的operator newoperator delete函数,之后再查找全局作用域是否有重新定义的operator newoperator delete函数,接着再调用标准库的operator newoperator delete函数。

c.当类内自定义operator new和operator delete函数时,默认为static函数,因为operator new发生在对象构造前,而operator delete发生在对象销毁后,不属于对象的生命周期内。

d.类型size_t是标准库定义的一种类型,不必传入实参,编译器会为我们计算需要的内存大小,并自行传入size_t形参。

上一篇下一篇

猜你喜欢

热点阅读