美文网首页
Week5(Boolan)

Week5(Boolan)

作者: DangerousMan | 来源:发表于2017-05-18 20:36 被阅读0次

    关于vptr和vtbl

    父类有虚函数,子类也必定有,并且含有自己的虚指针(vptr)。虚指针指向虚表(vtbl),虚表中存放函数指针,指向虚函数所在位置。父类和子类的同名成员函数完全无关联,是不同的函数。子类override的父类虚函数,拥有与父类不同的函数指针。

    静态绑定与动态绑定

    c语言中的函数调用(call)是静态绑定(static binding),调用函数时总是由编译器解析成固定地址然后跳转,调用结束再跳转回初始的地址。

    c++中通过指针调用虚函数是动态绑定,访问虚指针指向的虚表中含有的多个函数地址。


    让编译器理解成动态绑定(*p->vptr[n]) (p);得符合三个条件:

    1.通过指针调用

    2.指针是upcast向上转型 *A pa = new B A是B的父类

    3.调用的是虚函数


    虚函数的两种用法:

    1.template method 通过子类对象调用父类函数,将子类对象的地址(this pointer)作为参数传给父类函数(所有类的成员函数都有隐含的this pointer作为参数),在执行过程中遇到子类中特有的成员函数时跳转到子类,调用结束后又返回继续执行父类函数,正是利用了动态绑定的特性

    2.多态   声明容器中的指针时必须指向父类,在使用时可以让它指向子类


    关于const

    不能由const对象调用non-const函数(不保证data members不变):

    const String str(“hello world”);

    str.print();

    虽然const版本函数也可以被non-const object调用,但当成员函数的const和non-const版本同时存在,const object只能调用const版本,non-const object只能调用non-const版本

    array new

    array new时,数组的内存除了(元素个数*每个元素的大小)外,还有一个大小为4字节的数用来记录数组元素个数,使数组作为一个整体被分配内存,并且使编译器快速得知构造以及析构函数需要被调用的次数。

    绕过自己重载的构造以及析构函数,强制使用默认的全局函数的方法:

    Foo* p = ::new Foo(7);

    ::delete p;

    Foo* pArray = ::new Foo[5];

    ::delete []pArray;

    重载placement new:

    可以为operator new()写出多个版本,但每个版本的声明必须有独特的参数列(或者类型不同,或者参数个数不同),其中第一参数必须是size_t,其余参数以new()括号中指定的placement arguments为初值。

    也可以重载class member operator delete()并写出多个版本(参数列表与operator new对应,即使并未一一对应,也不会报错,意味着放弃处理ctor发出的异常),但只有当new所调用的ctor抛出exception,才会调用重载版的operator delete()。它主要用来归还未完全创建成功的对象所占的内存。

    相关文章

      网友评论

          本文标题:Week5(Boolan)

          本文链接:https://www.haomeiwen.com/subject/tnljxxtx.html