现在的位置: 首页 > 综合 > 正文

C++多态如何实现 | sys_brk原理

2017年12月25日 ⁄ 综合 ⁄ 共 1561字 ⁄ 字号 评论关闭
1、C++多态如何实现

重载overload是相同范围内,函数名相同,参数不同;

覆盖override不同范围内(派生类和基类),函数名相同,参数也相同,基类函数必须有virtual关键字;

重载的意义在于针对同一函数调用提供了多种可选版本;   
   
而覆盖一般是指派生类的成员函数去覆盖基类的(同名)成员函数,使在派生类的作用域内只有派生类自己那个成员函数可见,而要调用基类的同名函数,则需提供显示的域解析符::   
    
 多态是指用指向基类指针调用虚函数时,总能调用到正确的版本。也就是说,如果基类指针实际指向的是某个派生类对象,而这个派生类又覆盖了基类中定义的相应的虚函数,那么通过这个指针调用的成员函数,就是(所期望的)派生类自己定义的那个成员函数。

补充一下,刚看到一个隐藏的概念,跟覆盖区别一下
 令人迷惑的隐藏规则
本来仅仅区别重载与覆盖并不算困难,但是C++的隐藏规则使问题复杂性陡然增加。
这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual
关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual
关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。


2、
sys_brk支持c语言的 malloc和free函数 低级操作。malloc通过 调用sys_brk向内核申请一段虚拟地址空间 vma(线性区),建立地址映射,vma全部建立起与内存页的映射──通过mmap实现;free也通过这个系统调用告诉内核需要收回这个线性地址空间,取消已经建立的映射 。
sys_brk系统调用可以对用户进程的堆的大小进行操作,使堆扩展或者缩小。

1)
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序──即由内核的空闲区变成进程的线性区,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
2)
栈:在Windows,栈是向低地址扩展的数据结构,是一块连续的内存的区域( WINDOWS下,栈的大小是2M
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。(堆的大小受限于计算机系统中有效的虚拟内存

3)
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活


3
内核提供了kmalloc和kfree,分配真实地址已知的实际物理内存块,──映射到连续物理页框

还提供了vmalloc和vfree,用于对内核使用的虚拟内存进行分配和释放。vamalloc分配的虚拟地址空间在3G+high_memory+VMALLOC_OFFSET以上的高端,由vmlist链表管理。 3G是内核态访问物理内存的起始地址,high_memory是计算机实际可用的物理内存的最高地址,VMALLOC_OFFSET是8M的“隔离带”──映射到 非连续物理页框。

抱歉!评论已关闭.