1、静态多态和动态多态

静态多态:函数重载,模板。编译期间完成。

动态多态:虚函数。运行期间实现。

2、模板的实现和优缺点

函数模板的代码并不能直接编译成二进制代码,而是要实例出一个模板实例。写了模板的实现(定义)后,编译器在遇到需要实例的情况时才会进行实例。

优点:

增加了代码的重用性和可扩展性。减少开发时间。

缺点:

1.编译器不支持对模板的分离式编译,即所有基于模板的算法的定义实现都要放在头文件中,否则编译时可能不能生成模板的实例,使得在链接时报错。(也就是说,模板的定义都要放在.h文件中,不能声明放.h定义放.cpp)

2.可读性不好,调试困难。

3、构造、析构函数和抛出异常

能在析构函数中抛出异常吗?

语法上可以,但是实际中不能抛出异常。

1. 析构函数中抛出异常会打断他做的事情,可能无法释放申请的内存。

2. 如果无法避免析构函数抛出异常,那么应该让析构函数捕获任何异常,然后选择消化异常或者终止程序。

3. 析构函数抛出异常,然后进行栈展开寻找异常处理,栈展开过程中会自动清空函数的局部变量,调用函数中对象的析构函数,如果这时候又抛出一个异常,因为C++只能执行一个异常,程序会自动调用std::terminate(),终止程序。

能在构造函数中抛出异常吗?

构造函数可以抛出异常,但是要避免内存泄露。

1. 构造函数中抛出异常,该对象就没有被完全构造,就不会调用析构函数。那么已经new的对象就不会被释放,可能造成内存泄漏。

2. 解决的方法:一个是使用智能指针;二是捕获所有的异常,然后把申请的资源释放,再重新抛出异常。

4、构造、析构函数和虚函数

语法可以,但是实际中不能这么做。

不能在构造函数中调用虚函数?

在构建派生类对象时,基类的构造函数会先被调用,如果基类的构造函数中调用了虚函数,这时候调用的虚函数是基类版本的虚函数,而不是预想中的派生类的虚函数。因为基类的构造函数先调用,此时派生类的成员对象还未初始化,所以调用派生类的虚函数是不安全的。而且虚函数表指针是在构造函数中初始化的,不初始化调用不了正确的虚函数。

不能在析构函数中调用虚函数?

同理,派生类会先析构,再调用父类的析构函数。如果此时父类的析构函数调用了虚函数,那么只能调用父类版本的虚函数。

5、STL里的内存池实现

内存池概念

如果每次申请内存都向系统申请,因为操作系统分配内存很费时的,那么频繁的申请空间就会很耗时。内存池就是先向系统申请一大块内存,然后用户需要的时候再划分一部分给用户,这样效率高。

两级配置器

对于分配128byte的空间,使用第一级配置器以malloc,free实现;

分配小于128byte空间,则使用第二级配置器,用内存池管理。每次配置一大块内存,维护对应的16个自由链表(free-list)。自由链表分别管理大小为8、16、24、...、128的数据块,每次对于申请的大小在自由链表中找出一个满足的块。

指针数组+自由链表

内存池实现:

指针数组中第一个指针指向8byte块的自由链表,第二个指向16byte块自由链表,以此类推。

要分配一个块,那么先找出第一个满足要求的8的倍数的块,然后在指针数组中找到对应的位置,如果还有空闲块,就分配链表头的块出去,更新链表头的块;如果不足,则重新申请(默认20个)空闲块,然后分配。回收时同理,把回收的块放到链表头。

union obj{
union obj *next;//当使用next时、Obj所代表的的就是指向下一个节点的指针
char client[1]; //当使用data时、Obj本身就是实际的块空间
}

参考资料:

C++模板的定义是否只能放在头文件中?

Effective C++读书笔记(8): 析构函数不能抛出异常

SGI STL中内存池的实现

C++ part9的更多相关文章

  1. MMORPG大型游戏设计与开发(客户端架构 part9 of vegine)

    时间在人们的生活中是多么重要的东西,如果打乱了时间,不知道这个时间会成什么样子.在客户端中,自然也有时间模块,因为不同的时间可能会处理不同的事情,特别是在追求高度自由化的同时,时间也成为了一个很重要的 ...

  2. Python重写C语言程序100例--Part9

    ''' [程序71] 题目:编写input()和output()函数输入,输出5个学生的数据记录. 1.程序分析: 2.程序源码: 使用list来模拟结构(不使用class) stu = [strin ...

  3. part9 公用图片画廊组件拆分

    1.src中创建 common 再创建 gallery.然后gallery.vue 2.build 中webpack.base.conf 中配置更短路径 module.exports {}中 reso ...

  4. Atitit.attilax软件研发与项目管理之道

    Atitit.attilax软件研发与项目管理之道 1. 前言4 2. 鸣谢4 3. Genesis 创世记4 4. 软件发展史4 5. 箴言4 6. 使徒行传 4 7. attilax书 4 8. ...

  5. 浪潮 NF5240M3 ,NP5540M3 服务器安装2008 R2

    1,服务器系统的安装会出现错误的地方一般都是在Raid 卡驱动 略过Raid 卡配置, 具体 http://jingyan.baidu.com/article/ca41422fddfd201eae99 ...

  6. R12_专题知识总结提炼-AR模块

    应收模块简介 应收模块是用来为企业提供应收款管理的模块. 当企业销售一笔商品或者发生其他影响收入和现金的业务的时候,需要在应收模块记账. 本文档以R12为例,11i可参考,只针对简单业务情况考虑,将应 ...

  7. SHELL实现同时操作多个服务器:服务器批量管理

    引言:     1.如果你想知道你所管理的几万台服务器的/home分区使用率是多少.     2.如果你想为你所管理的几万台服务器添加同一个计划任务你该怎么办?     3.如果你想让你所管理的几万台 ...

  8. javascript的基本语法、数据结构

    本篇学习资料主要讲解javascript的基本语法.数据结构      无论是传统的编程语言,还是脚本语言,都具有数据类型.常量和变量.运算符.表达式.注释语句.流程控制语句等基本元素构成,这些基本元 ...

  9. 在node.js中使用mongose模块

    对象与文档相对应 创建项目目录,用root进入 # mkdir /home/test/part9/ 直接# npm install mongoose,报错如下 ../node_modules/nan/ ...

随机推荐

  1. MySQL数据库基础知识及优化

    MySQL数据库基础知识及优化必会的知识点,你掌握了多少? 推荐阅读: 这些必会的计算机网络知识点你都掌握了吗 关于数据库事务和锁的必会知识点,你掌握了多少? 关于数据库索引,必须掌握的知识点 目录 ...

  2. SpringCloud Alibaba Nacos注册中心源码浅析

    一.前置了解 1.1 简介 Nacos是一款阿里巴巴推出的一款微服务发现.配置管理框架.我们本次对将对它的服务注册发现功能进行简单源码分析. 1.2 流程 Nacos的分析分为两部分,一部分是我们的客 ...

  3. 原生ajax分享

    最近被大佬问了一个很有趣的问题,你还能手打出一个ajax吗?,我当时的想法是有现成的为什么要自己打,后来我反思了一下(只有靠自己才是强者),在这里给大家分享一个我自己打的ajax,也是自己的一个知识点 ...

  4. 【UltraISO】中文破解版

    下载链接:https://cn.ultraiso.net/uiso9_cn.exe简体中文版专用:   注册名:Guanjiu    注册码:A06C-83A7-701D-6CFC多国语言版专用:   ...

  5. (10)-Python3之--引入

    1.什么是模块 .py文件就是模块 模块名有命名要求: 1.不要以数字.下划线开头.特殊符号.也不要以中文开头. 2.通常来说,都是以字母开头. 3.不要以关键字来命名.内置函数.内置模块.不要以第三 ...

  6. NIO非阻塞网络编程原理

    NIO非阻塞网络编程原理 1.NIO基本介绍 Java NIO 全称 java non-blocking IO,是指 JDK 提供的新 API.从 JDK1.4 开始,Java 提供了一系列改进的 输 ...

  7. 奇艺iOS移动端网络优化实践 | 请求成功率优化篇 原创 Charles 爱奇艺技术

    奇艺iOS移动端网络优化实践 | 请求成功率优化篇 原创 Charles 爱奇艺技术

  8. numpy pandas 学习

    一. 数组要比列表效率高很多 numpy高效的处理数据,提供数组的支持,python默认没有数组.pandas.scipy.matplotlib都依赖numpy. pandas主要用于数据挖掘,探索, ...

  9. Spring Boot 整合 Freemarker

    Spring Boot 整合 Freemarker 1.Freemarker 简介 2.Spring Boot 整合 Freemarker 2.1 创建工程 2.2 创建类 2.3 其他配置 原文地址 ...

  10. js创建map

    function Map() { var struct = function(key, value) { this.key = key; this.value = value; } var put = ...