30 : Understand the ins and outs of inlining


1 inline申请书

1.1 类内部实现函数包含隐藏的inline申请

class Human {
public:
Human() { } // 这个也是inline函数吗?参考3.2
int age() const { return m_age; } //隐喻的内联申请
private:
int m_age;
};

1.2 virtual与inline

一个virtual函数不可能是inline函数,或者说不可能是inline候选人。virtual为运行时派,而inline是编译时派。

1.3 模版与inline

如果可能或没有必要,请不要使用inline,来避免代码量的增加。

1.4 如果inline申请失败的话

请不要担心,编译器会给出一个警告。(见条款53)

2 inline的模样

2.1 inline的位置和处理

inline函数通常被放置在头文件中,因为大部分编译器在编译阶段进行内联函数展开。而少数编译器,例如.Net CLI(Common Language Infrastructrue)可在运行时期完成内联,这是绝对的例外。inline函数应该在编译阶段被处理。

3 inline障眼法

3.1 力不从心的编译器

有时候编译器想inlining一个函数,但他不能这么做。例如需要获取一个函数的地址时,还是不得不产生一个函数本体。

3.2 构造析构函数与inline所带来的思考

这两者为inline的糟糕候选人。

C++保证了一系列的发生动作,然而并没有保证动作如何发生

如果一个类有许多的成员变量,那他们将在构造函数中进行默认构造。我们知道这件事会发生,但不清楚编译器如何进行这些操作。假设每个操作都是异常安全的,并且析构函数为inline,那么构造函数中将会出现大量的自身的析构函数副本、成员变量的析构函数副本,构造函数将变得异常庞大。当类有继承关系时,情况更糟糕。

4 重视inline

4.1 评估inline冲击

修改inline函数将导致客户的与该函数相关的代码全部重新编译。

4.2 调试器束手无策

调试器对一个没有本体的函数束手无策,你应该去何处打断点呢?

4.3 黄金法则 80-20

起初不要进行inline声明,找出那80%的时间在运行的20%的代码进行inline优化。   这条法则也说明了先实现再优化的办事原则,而inline属于优化阶段。

请记住

1 将大多数inlinin限制在小型、频繁调用的函数身上,这可是日后的调试过程和二进制升级(binary upgradability)更容易,也可使潜在的代码膨胀问题最小化,是程序的速度提升机会最大化。

2 不要只因为function templates出现在头文件就将他们声明为inline,

专业词汇


指令高速缓存装置的击中率(instruction cache hit rate)
二进制升级(binary upgradability)
CLI(Common Language Infrastructrue)

Effective C++ 笔记:条款 30 inline的更多相关文章

  1. [Effective JavaScript 笔记]第30条:理解prototype、getPrototypeOf和__ptoto__之间的不同

    原型包括三个独立但相关的访问器.这三个单词都是对单词prototype做了一些变化. C.prototype用于建立由new C()创建的对象的原型 Object.getPrototypeOf(obj ...

  2. Effective STL 学习笔记 Item 30: 保证目标区间足够大

    Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...

  3. [Effective JavaScript 笔记]第3章:使用函数--个人总结

    前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...

  4. Effective C++笔记:实现

    条款26:尽可能延后变量定义式的出现时间 博客地址:http://www.cnblogs.com/ronny/ 转载请注明出处! 有些对象,你可能过早的定义它,而在代码执行的过程中发生了导常,造成了开 ...

  5. Effective C++笔记05:实现

    条款26:尽可能延后变量定义式的出现时间 博客地址:http://blog.csdn.net/cv_ronny 转载请注明出处! 有些对象,你可能过早的定义它,而在代码运行的过程中发生了导常,造成了開 ...

  6. Effective C++ 50条款

    条款1:尽量用const和inline而不用#define 以const 行使常量折叠,用inline 代替常用操作的宏定义,而且库里面有很多常用函数可用.当然不能抛弃宏,宏还是很有用滴.偶最近才发现 ...

  7. Effective C++笔记(五):实现

    参考:http://www.cnblogs.com/ronny/p/3754755.html 条款26:尽可能延后变量定义式的出现时间 有些对象,你可能过早的定义它,而在代码执行的过程中发生了导常,造 ...

  8. Effective Java笔记一 创建和销毁对象

    Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...

  9. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

随机推荐

  1. linux git pull/push时提示输入账号密码之免除设置

    1.先cd到根目录,执行git config --global credential.helper store命令 [root@iZ25mi9h7ayZ ~]# git config --global ...

  2. eclipse各版本及下载

    附:Eclipse各个版本简介(http://zh.wikipedia.org/wiki/Eclipse) eclipse下载地址: https://www.eclipse.org/官网--右上角的I ...

  3. KPPW2.5 漏洞利用--CSRF

    kppw2.5 CSRF漏洞复现 漏洞说明 http://192.168.50.157/kppw25/index.php?do=user&view=message&op=send 收件 ...

  4. SQL Server 2012无法连接到WMI提供程序

    这篇文章主要介绍了SQL Server 2012无法连接到WMI提供程序(Cannot connect to WMI provider)解决方案,需要的朋友可以参考下 今天一位同事在启动自己工作机的S ...

  5. java的环境配置

    java的安装 1,进入官网  https://www.oracle.com/index.html 2.Menu -> Downloads -> java ->  all Java ...

  6. JAVA多线程17个问题

    1.Thread 类中的start() 和 run() 方法有什么区别? Thread.start()方法(native)启动线程,使之进入就绪状态,当cpu分配时间该线程时,由JVM调度执行run( ...

  7. ARCore中四元数的插值算法实现

    ARCore中四元数差值算法: 其中t的取值范围为[0, 1],当 t = 0 时,结果为a:当t = 1 时,结果为b. public static Quaternion makeInterpola ...

  8. django 数据库查询的几个知识点

    django查询db过程中遇到的几个问题: 1. 数据库切换,用using products = models.TProductCredit.objects.using(') 2.查询结构集是Quer ...

  9. [原]vue中各模块的实际引用

    检查发现: 1.vue实际引用文件配置位置 alias: { 'vue$': 'vue/dist/vue.esm.js', 此位置替换了vue包内的package.json中定义的位置 } 2.vue ...

  10. Javascript中 toFixed

    javascript中toFixed使用的是银行家舍入规则. 银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法. 简单来说就是:四舍六入五考虑,五后非零就进一,五后为零 ...