分类: C/C++
2013-06-27 16:57:09
1,C++ inline用法:
An inline function represents a request to the compiler to expand the function at each call point. With an inline function, the compiler replaces the function call with a copy of the code to be executed.//inline会向编译器请求在每个调用点展开函数。inline函数中,编译器用将要执行的原代码的一份拷贝来代替函数调用。
The inline specification is only a request to the compiler. Whether the compiler actually honors the request is implementation-dependent.//inline规则只是向编译器作一个请求,编译器是否真正接受这个请求与实现相关。
关于更多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函数只有一个定义,且程序员无需复制代码,并且不可能在程序的生命期中引起无意的不匹配的事情。
慎用内联
内联能提高函数的执行效率,为什么不把所有的函数都定义成内联函数?如果所有的函数都是内联函数,还用得着“内联”这个关键字吗?内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。
以下情况不宜使用内联:
(1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。
(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。类的构造函数和析构函数容易让人误解成使用内联更有效。要当心构造函数和析构函数可能会隐藏一些行为,如“偷偷地”执行了基类或成员对象的构造函数和析构函数。所以不要随便地将构造函数和析构函数的定义体放在类声明中。一个好的编译器将会根据函数的定义体,自动地取消不值得的内联(这进一步说明了 inline 不应该出现在函数的声明中)。
2,函数重载
函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。
为什么需要函数重载?
?试想如果没有函数重载机制,如在C中,你必须要这样去做:为这个print函数取不同的名字,如print_int、print_string。这里还只是两个的情况,如果是很多个的话,就需要为实现同一个功能的函数取很多个名字,如加入打印long型、char*、各种类型的数组等等。这样做很不友好!
?类的构造函数跟类名相同,也就是说:构造函数都同名。如果没有函数重载机制,要想实例化不同的对象,那是相当的麻烦!
?操作符重载,本质上就是函数重载,它大大丰富了已有操作符的含义,方便使用,如+可用于连接字符串等!
更多关于函数重载的知识,可以查看:http://www.cnblogs.com/skynet/archive/2010/09/05/1818636.html
3,模板函数
void display_message(const string& msg, vector
void display_message(const string& msg, vector
两个函数,其内容大部分都是相同的,只有一个参数的类型不一样,这种情况可以使用模板函数。
A function template begins with the keyword template . It is followed by a list of one or more identifiers that represent the types we wish to defer. The list is set off by a less-than/greater-than bracket pair (< , > ). The user supplies the actual type information each time he uses a particular instance of the function. These identifiers in effect serve as placeholders for actual data types within the parameter list and body of the function template. //Essential C++上的原话
模板函数与函数重载:
In general, we overload a function when there are multiple implementations, but each instance provides the same general service. We make a function a template when the body of the code remains invariant across a variety of types.
//Essential C++上的原话
//一般情况下,当有多个函数实现,并且每个函数都提供相同的功能时,用函数重载。当代码主体相同,只是变量的数据类型不同时,用函数模板。
可以参考:http://blog.renren.com/blog/231887749/503757691