1.多态的实现 存在虚函数的类至少有一个(多继承会有多个)一维的虚函数表叫做虚表(virtual table),属于类成员,虚表的元素值是虚函数的入口地址,在编译时就已经为其在数据端分配了空间。
编译器另外还为每个类的对象提供一个虚表指针(vptr),指向虚表入口地址,属于对象成员。
在实例化派生类对象时,先实例化基类,将基类的虚表入口地址赋值给基类的虚表指针,当基类构造函数执行完时,再将派生类的虚表入口地址赋值给基类的虚表指针(派生类和基类此时共享一个虚表指针,并没有各自都生成一个),在执行父类的构造函数。
以上是C++多态的实现过程,可以得出结论:
1.有虚函数的类必存在一个虚表。 2.虚表的构建:基类的虚表构建,先填上虚析构函数的入口地址,之后所有虚函数的入口地址按在类中声明顺序填入虚表;派生类的虚表构建,先将基类的虚表内容复制到派生类虚表中,如果派生类覆盖了基类的虚函数,则虚表中对应的虚函数入口地址也会被覆盖,为了后面寻址的一致性。 虚函数表中有序放置了父类和子类中的所有虚函数,并且相同虚函数在类继承链中的每一个虚函数表中的偏移量都是一致的。所以确定的虚函数对应virtual table中一个固定位置n,n是一个在编译时期就确定的常量,所以,使用vptr加上对应的n,就可以得到对应的函数入口地址。
Read more →
垃圾回收算法 垃圾:无法再被访问的对象或内存空间。
延迟:指平均每次垃圾回收开始到结束需要的时间。
吞吐量:指平均一定时间内能回收多少内存,内存多少这个概念非常广泛,可以指多少个对象,也可以指多少字节的空间,具体的应该看指标应需求而异。
根节点:如全局变量上的对对象的引用、栈上对对象的引用等用户一定能够访问到的地址,是寻找活对象的入口。
1.引用计数 这是最初级的垃圾收集算法。此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。我们可以为每个对象都增加一个计数器,来记录对这个对象的引用数量,当引用计数归零时,这个对象变成了垃圾。
优点:
(1)内存释放及时,当一个对象死亡时其占用的内存马上被释放 (2)延迟低,内存释放的时间均匀地分布在各个时间段 缺点:
Read more →
简述 闭包是js的一个难点也是它的一个特色,是我们必须掌握的js高级特性,那么什么是闭包呢?它又有什么用呢?
我们都知道,js的作用域分两种,全局和局部,基于我们所熟悉的作用域链相关知识,我们知道在js作用域环境中访问变量的权利是由内向外的,内部作用域可以获得当前作用域下的变量并且可以获得当前包含当前作用域的外层作用域下的变量,反之则不能,也就是说在外层作用域下无法获取内层作用域下的变量,同样在不同的函数作用域中也是不能相互访问彼此变量的,那么我们想在一个函数内部也有限权访问另一个函数内部的变量该怎么办呢?闭包就是用来解决这一需求的,闭包的本质就是在一个函数内部创建另一个函数。
我们首先知道闭包有3个特性:
①函数嵌套函数
②函数内部可以引用函数外部的参数和变量
③参数和变量不会被垃圾回收机制回收
function a() { var i = 0; function b() { alert(++i); } return b; } var c = a(); c(); 这段代码有两个特点:
Read more →
求出反码中2的个数 class Solution { public: int NumberOf1(int n) { unsigned int m = n; int count = 0; while(m) { count += (m&1); m = m>>1; } return count; } }; unsigned 可以将int转换一下,有符号整数变为无符号数。
Read more →
判断链表是否有环 方法 快慢指针
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: bool hasCycle(ListNode *head) { ListNode * p1 = head, * p2 = head; while(p2 !
Read more →