c++中inline的用法分析

在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联。
inline int min(int first, int secend) {/****/};
inline函数对编译器而言必须是可见的,以便它能够在调用点内展开该函数。与非inline
函数不同的是,inline函数必须在调用该函数的每个文本文件中定义。当然,对于同一程序
的不同文件,如果inline函数出现的话,其定义必须相同。对于由两个文件compute.C和draw.C构成的程序来说,程序员不能定义这样的min()函数,它在compute.C中指一件事情,
而在draw.C中指另外一件事情。如果两个定义不相同,程序将会有未定义的行为:

为保证不会发生这样的事情,建议把inline函数的定义放到头文件中。在每个调用该inline函数的
文件中包含该头文件。这种方法保证对每个inline函数只有一个定义,且程序员无需复制代码,并且
不可能在程序的生命期中引起无意的不匹配的事情。
(二)内联函数的编程风格(摘自高质量C++/C 编程指南)
关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用。
如下风格的函数Foo 不能成为内联函数:


代码如下:

inline void Foo(int x, int y); // inline 仅与函数声明放在一起
int main() {

}
void Foo(int x, int y)
{
}

而如下风格的函数Foo 则成为内联函数:


代码如下:

void Foo(int x, int y)
int main() {

}
inline void Foo(int x, int y) // inline 与函数定义体放在一起
{
}

所以说,inline 是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。
一般地,用户可以阅读函数的声明,但是看不到函数的定义。尽管在大多数教科书中内
联函数的声明、定义体前面都加了inline 关键字,但我认为inline 不应该出现在函数
的声明中。这个细节虽然不会影响函数的功能,但是体现了高质量C++/C 程序设计风格
的一个基本原则:声明与定义不可混为一谈,用户没有必要、也不应该知道函数是否需
要内联。
定义在类声明之中的成员函数将自动地成为内联函数,例如


代码如下:

class A
{
public:
void Foo(int x, int y) { } // 自动地成为内联函数
}

将成员函数的定义体放在类声明之中虽然能带来书写上的方便,但不是一种良好的编程
风格,上例应该改成:


代码如下:

// 头文件
class A
{
public:
void Foo(int x, int y);
}
// 定义文件
inline void A::Foo(int x, int y)
{
}

慎用内联
内联能提高函数的执行效率,为什么不把所有的函数都定义成内联函数?
如果所有的函数都是内联函数,还用得着“内联”这个关键字吗?
内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的
执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收
获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,
消耗更多的内存空间。以下情况不宜使用内联:
(1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。
(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。
类的构造函数和析构函数容易让人误解成使用内联更有效。要当心构造函数和析构
函数可能会隐藏一些行为,如“偷偷地”执行了基类或成员对象的构造函数和析构函数。
所以不要随便地将构造函数和析构函数的定义体放在类声明中。
一个好的编译器将会根据函数的定义体,自动地取消不值得的内联(这进一步说明
了inline 不应该出现在函数的声明中)。

(0)

相关推荐

  • C++ 关键字 inline详细介绍

    1.  内联函数 在C++中我们通常定义以下函数来求两个整数的最大值: 复制代码 代码如下: int max(int a, int b){ return a > b ? a : b;} 为这么一个小的操作定义一个函数的好处有: ① 阅读和理解函数 max 的调用,要比读一条等价的条件表达式并解释它的含义要容易得多 ② 如果需要做任何修改,修改函数要比找出并修改每一处等价表达式容易得多 ③ 使用函数可以确保统一的行为,每个测试都保证以相同的方式实现 ④ 函数可以重用,不必为其他应用程序重写代码 虽

  • c++内联函数(inline)使用详解

    介绍内联函数之前,有必要介绍一下预处理宏.内联函数的功能和预处理宏的功能相似.相信大家都用过预处理宏,我们会经常定义一些宏,如 复制代码 代码如下: #define TABLE_COMP(x) ((x)>0?(x):0) 就定义了一个宏. 为什么要使用宏呢?因为函数的调用必须要将程序执行的顺序转移到函数所存放在内存中的某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方.这种转移操作要求在转去执行前要保存现场并记忆执行的地址,转回后要恢复现场,并按原来保存地址继续执行.因此,函数调

  • C++中inline函数详解

    本文主要记录了C++中的inline函数,也就是内联函数,主要记录了以下几个问题: 一.C++为什么引入inline函数? 主要目的:用它代替C语言中表达式形式的宏定义来解决程序中函数调用的效率问题. C语言中的宏定义:#define ExpressionName(var1,var2) (var1+var2)*(var1-var2)这种宏定义,它使用预处理器实现,没有了参数压栈.代码生成等一系列得到操作,因此效率很高.但缺点如下: 仅仅是做预处理器符号表中的简单替换,因此不能进行参数有效性的检测

  • C++实现inline hook的原理及应用实例

    本文实例简述了C++实现inline hook的原理及应用,对于大家更好的理解inline hook原理及其应用有很大的帮助.具体内容如下: 一.Inline Hook简介: 1.INLINE HOOK原理: Inline Hook通过硬编码的方式向内核API的内存空间(通常是开始的一段字节,且一般在第一个call之前,这么做是为了防止堆栈混乱)写入跳转语句,这样,该API只要被调用,程序就会跳转到我们的函数中来,我们在自己写的函数里需要完成3个任务: 1)重新调整当前堆栈.程序流程在刚刚跳转的

  • C/C++中static,const,inline三种关键字详细总结

    一.关于staticstatic 是C++中很常用的修饰符,它被用来控制变量的存储方式和可见性,下面我将从 static 修饰符的产生原因.作用谈起,全面分析static 修饰符的实质. static 的两大作用: 一.控制存储方式 static被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间. 引出原因:函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保

  • 详解C++中的inline用法

    1. 引入inline关键字的原因 在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数. 栈空间就是指放置程序的局部数据(也就是函数内数据)的内存空间. 在系统下,栈空间是有限的,假如频繁大量的使用就会造成因栈空间不足而导致程序出错的问题,如,函数的死循环递归调用的最终结果就是导致栈内存空间枯竭. 下面我们来看一个例子: #include <stdio.h> //函数定义为inline即:内联函数 inline char*

  • c++ 尽量不要使用#define 而是用const、enum、inline替换。

    例如:这里程序文件开头有如下#define语句 复制代码 代码如下: #define N 10 #define PI 3.14 #define MAX 10000 #define Heigth 6.65 ... ... 假设这里程序运行出错误,而且就是在我们使用这些常量有错误,此时编辑器应该会抛出错误信息.如果该信息提示6.65这里有错误,Ok如果你运气好你正好记得或者程序简单一眼能找到6.65表示什么,如果程序很复杂,而且报出6.65的文件是引用该文件,不记得,那么你会困惑这是什么?或许会花大

  • c++中inline的用法分析

    在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联. inline int min(int first, int secend) {/****/};inline函数对编译器而言必须是可见的,以便它能够在调用点内展开该函数.与非inline函数不同的是,inline函数必须在调用该函数的每个文本文件中定义.当然,对于同一程序的不同文件,如果inline函数出现的话,其定义必须相同.对于由两个文件compute.C和draw.C构成的程序来说,程序员不能定义这样的min(

  • jQuery中get方法用法分析

    本文实例讲述了jQuery中get方法用法.分享给大家供大家参考,具体如下: 参数:url,[data],[callback],[type] url 待载入页面的URL地址. data 待发送 Key/value 参数. callback 载入成功时回调函数. type 返回内容格式,xml, html, script, json, text, _default. 案例1 表单代码: <form id="form1" action="#"> <p&

  • python中split方法用法分析

    本文实例讲述了python中split方法用法.分享给大家供大家参考.具体分析如下: split 是非常重要的字符串方法,它是join的逆方法,用来将字符串分割成序列 >>> '1+2+3+4+5'.split('+') ['1', '2', '3', '4', '5'] >>> 'usr/bin/env'.split('/') ['usr', 'bin', 'env'] >>> 'usr/bin/env'.split('/') ['usr', 'bi

  • javascript中eval函数用法分析

    本文实例分析了javascript中eval函数用法.分享给大家供大家参考.具体分析如下: eval()只有一个参数,如果传入的参数不是字符串,则直接返回这个参数.否则会将字符串当成js代码进行编译,如果编译失败则抛出语法错误(SyntaxError)异常.如果编译成功则开始执行这段代码,并返回字符串中的最后一个表达式或语句的值:如果最后一个表达式或语句没有值,则最终返回undefined.如果字符串抛出异常,则该异常将把该调用传递给eval(); eval()最为重要的是,它使用了调用它的变量

  • C#类中static变量用法分析

    本文实例讲述了C#类中static变量用法.分享给大家供大家参考.具体分析如下: 先来看一段代码: 复制代码 代码如下: using System; namespace Param { class Class1 { static int i = getNum(); int j = getNum(); static int num = 1; static int getNum() { return num; } [STAThread] static void Main(string[] args)

  • php中in_array函数用法分析

    本文实例分析了php中in_array函数用法.分享给大家供大家参考.具体如下: PHP是弱类型语言 在使用IN_ARRAY函数时尽量带上第三个参数,代码如下: 复制代码 代码如下: var_dump(in_array(0,array('s','sss'),true)); // return false     var_dump(in_array(0,array('s','sss')));       // return true     var_dump(in_array(0,array(1,

  • php中stdClass的用法分析

    本文实例分析了php中stdClass的用法.分享给大家供大家参考.具体分析如下: stdclass在php中是预定义的几个类之一,是zent保留的一个类.实际上它是PHP提供的一个基类,就是一个空白的类,里面什么都没有,我们可以实例化它,然后定义一系列的变量,通过它来进行变量的传递(很多php程序员用它来传递一系列变量的值,而同时又懒得去创建一个自己的类).但是,由于实例化后不能添加方法,只能传递属性.因为,一旦类被实列化以后,就不能在添加方法了. stdclass可以作为基类使用,其最大特点

  • python中的全局变量用法分析

    本文实例分析了python中的全局变量用法.分享给大家供大家参考.具体分析如下: Python是一种面向对象的开发语言,在函数中使用全局变量,一般应作全局变量说明,只有在函数内经过说明的全局变量才能使用,这里就来介绍下Python全局变量有关问题. 首先应该说明的是需要尽量避免使用Python全局变量.不同的模块都可以自由的访问全局变量,可能会导致全局变量的不可预知性.对全局变量,如果程序员甲修改了_a的值,这时可能导致程序中的错误.这种错误是很难发现和更正的. 全局变量降低了函数或模块之间的通

  • C#中var关键字用法分析

    本文实例分析了C#中var关键字用法.分享给大家供大家参考.具体方法如下: C#关键字是伴随着.NET 3.5以后,伴随着匿名函数.LINQ而来, 由编译器帮我们推断具体的类型.总体来说,当一个变量是局部变量(不包括类级别的变量),并且在声明的时候初始化,是使用var关键字的前提.具体什么时候使用,什么时候不使用,以下是个人浅见. 1.声明匿名函数时使用var关键字 复制代码 代码如下: var temp = new {Name="", Category=""};

  • C#中的集合用法分析

    本文实例讲述了C#中的集合用法,分享给大家供大家参考.具体分析如下: [集合不同于数组,是一组可变类型的.可变数量的元素的组合,这些元素可能共享某些特征,需要以某种操作方式一起进行操作.一般来讲,为了便于操作这些元素的类型是相同的] [集合与数组的区别:数组是连续的.同一类型数据的一块区域,而集合可以是不连续的,多种数据类型] [在集合中 foreach() 也是适用的] 1·集合的定义: 复制代码 代码如下: ArrayList al = new ArrayList();  //定义一个 集合

随机推荐