内联函数FAQ
来源:互联网 发布:淘宝图片很不清楚 编辑:程序博客网 时间:2024/04/30 12:38
[9] 内联函数
(part of c++ faq lite, copyright ? 1991-96, marshall cline, cline@parashift.com)
--------------------------------------------------------------------------------
faqs in section [9]:
[9.1] 内联函数是什么?
[9.2] 内联函数是如何在安全和速度上取得折衷?
[9.3] 为什么我应该用内联函数?而不是原来清晰的 #define 宏?
[9.4] 如何告诉编译器使非成员函数成为内联函数?
[9.5] 如何告诉编译器使一个成员函数成为内联函数?
[9.6] 有其它方法告诉编译器使成员函数成为内联吗?
[9.7] 内联函数保证执行的更好吗?
--------------------------------------------------------------------------------
[9.1] 内联函数是什么?
内联函数是代码被插入到调用者代码串处的函数。如同 #define 宏,内联函数通过避免调用
开销来提高执行效率,尤其是它能够通过调用(“过程集成”)被编译器优化。
--------------------------------------------------------------------------------
[9.2] 内联函数是如何在安全和速度上取得折衷?
在 c 中,你可以通过在结构中设置一个 void* 来得到“封装的结构”,在这种情况下,指向
实际数据的 void* 指针对于结构的用户来说是未知的。因此结构的用户不知道如何解释void*
指针所指内容,但是存取函数可以将 void* 转换成被隐藏的类型。这是封装的一种形式。
不幸的是这样做丧失了类型安全,并且也将繁琐的对结构中的每个域的访问强加于函数调用。
(如果你允许直接存取结构的域,那么对任何能直接存取的人来说,了解如何解释 void* 指针
所指内容就是必要的了;这样将使改变底层数据结构变的困难)
虽然函数调用开销是很小的,但它会被累积。c++类允许函数调用以内联展开。这样让你在得到
封装的安全性时,同时得到直接存取的速度。此外,内联函数的参数类型由编译器检查,这是
对 c 的 #define 宏的一个改进。
--------------------------------------------------------------------------------
[9.3] 为什么我应该用内联函数?而不是原来清晰的 #define 宏?
因为 #define 宏是有害的。
和 #define 宏不同的是,内联函数总是对参数只精确地进行一次求值,从而避免了声名狼
藉的宏错误。换句话说,调用内联函数和调用正规函数是等价的,差别仅仅是更快:
// 返回 i 的绝对值的宏
#define unsafe(i) ( (i) > = 0 ? (i) : -(i) )
// 返回 i 的绝对值的内联函数
inline
int safe(int i)
{
return i > = 0 ? i : -i;
}
int f();
void usercode(int x)
{
int ans;
ans = unsafe(x++); // 错误!x 被增加两次
ans = unsafe(f()); // 危险!f()被调用两次
ans = safe(x++); // 正确! x 被增加一次
ans = safe(f()); // 正确! f() 被调用一次
}
和宏不同的,还有内联函数的参数类型被检查,并且被正确地进行必要的转换。
宏有害你的健康;万不得已不要用。
--------------------------------------------------------------------------------
[9.4] 如何告诉编译器使非成员函数成为内联函数?
声明内联函数看上去和普通函数非常相似:
void f(int i, char c);
当你定义一个内联函数时,在函数定义前加上 inline 关键字,并且将定义放入头文件:
inline
void f(int i, char c)
{
// ...
}
注意:将函数的定义({...}之间的部分)放在头文件中是强制的,除非该函数仅仅被单
个 .cpp 文件使用。尤其是,如果你将内联函数的定义放在 .cpp 文件中并且在其他 .cpp
文件中调用它,连接器将给出“unresolved external”错误。
--------------------------------------------------------------------------------
[9.5] 如何告诉编译器使一个成员函数成为内联函数?
声明内联成员函数看上去和普通函数非常类似:
class fred {
public:
void f(int i, char c);
};
但是当你定义内联成员函数时,在成员函数定义前加上 inline 关键字,并且将定义放入
头文件中。
inline
void fred::f(int i, char c)
{
// ...
}
通常将函数的定义({...}之间的部分)放在头文件中是强制的。如果你将内联函数的定义
放在 .cpp 文件中并且在其他 .cpp 文件中调用它,连接器将给出“unresolved external”
错误。
--------------------------------------------------------------------------------
[9.6] 有其它方法告诉编译器使成员函数成为内联吗?
有:在类体内定义成员函数:
class fred {
public:
void f(int i, char c)
{
// ...
}
};
尽管这对于写类的人来说很容易,但由于它将类是“什么”(what)和类“如何”(how)工作混
在一起,给阅读的人带来了困难。我们通常更愿意在类体外使用 inline 关键字定义成员函数
来避免这种混合。这种感觉所基于的认识是:在一个面向重用的世界中,使用你的类的人有很
多,而建造它的人只有一个(你自己);因此你做任何事都应该照顾多数而不是少数。
--------------------------------------------------------------------------------
[9.7] 内联函数保证执行的更好吗?
不。
小心过度使用内联函数可能导致代码膨胀。在页面调度环境中,它可能会给执行带来负面影响。
--------------------------------------------------------------------------------
revised sep 8, 1997
(part of c++ faq lite, copyright ? 1991-96, marshall cline, cline@parashift.com)
--------------------------------------------------------------------------------
faqs in section [9]:
[9.1] 内联函数是什么?
[9.2] 内联函数是如何在安全和速度上取得折衷?
[9.3] 为什么我应该用内联函数?而不是原来清晰的 #define 宏?
[9.4] 如何告诉编译器使非成员函数成为内联函数?
[9.5] 如何告诉编译器使一个成员函数成为内联函数?
[9.6] 有其它方法告诉编译器使成员函数成为内联吗?
[9.7] 内联函数保证执行的更好吗?
--------------------------------------------------------------------------------
[9.1] 内联函数是什么?
内联函数是代码被插入到调用者代码串处的函数。如同 #define 宏,内联函数通过避免调用
开销来提高执行效率,尤其是它能够通过调用(“过程集成”)被编译器优化。
--------------------------------------------------------------------------------
[9.2] 内联函数是如何在安全和速度上取得折衷?
在 c 中,你可以通过在结构中设置一个 void* 来得到“封装的结构”,在这种情况下,指向
实际数据的 void* 指针对于结构的用户来说是未知的。因此结构的用户不知道如何解释void*
指针所指内容,但是存取函数可以将 void* 转换成被隐藏的类型。这是封装的一种形式。
不幸的是这样做丧失了类型安全,并且也将繁琐的对结构中的每个域的访问强加于函数调用。
(如果你允许直接存取结构的域,那么对任何能直接存取的人来说,了解如何解释 void* 指针
所指内容就是必要的了;这样将使改变底层数据结构变的困难)
虽然函数调用开销是很小的,但它会被累积。c++类允许函数调用以内联展开。这样让你在得到
封装的安全性时,同时得到直接存取的速度。此外,内联函数的参数类型由编译器检查,这是
对 c 的 #define 宏的一个改进。
--------------------------------------------------------------------------------
[9.3] 为什么我应该用内联函数?而不是原来清晰的 #define 宏?
因为 #define 宏是有害的。
和 #define 宏不同的是,内联函数总是对参数只精确地进行一次求值,从而避免了声名狼
藉的宏错误。换句话说,调用内联函数和调用正规函数是等价的,差别仅仅是更快:
// 返回 i 的绝对值的宏
#define unsafe(i) ( (i) > = 0 ? (i) : -(i) )
// 返回 i 的绝对值的内联函数
inline
int safe(int i)
{
return i > = 0 ? i : -i;
}
int f();
void usercode(int x)
{
int ans;
ans = unsafe(x++); // 错误!x 被增加两次
ans = unsafe(f()); // 危险!f()被调用两次
ans = safe(x++); // 正确! x 被增加一次
ans = safe(f()); // 正确! f() 被调用一次
}
和宏不同的,还有内联函数的参数类型被检查,并且被正确地进行必要的转换。
宏有害你的健康;万不得已不要用。
--------------------------------------------------------------------------------
[9.4] 如何告诉编译器使非成员函数成为内联函数?
声明内联函数看上去和普通函数非常相似:
void f(int i, char c);
当你定义一个内联函数时,在函数定义前加上 inline 关键字,并且将定义放入头文件:
inline
void f(int i, char c)
{
// ...
}
注意:将函数的定义({...}之间的部分)放在头文件中是强制的,除非该函数仅仅被单
个 .cpp 文件使用。尤其是,如果你将内联函数的定义放在 .cpp 文件中并且在其他 .cpp
文件中调用它,连接器将给出“unresolved external”错误。
--------------------------------------------------------------------------------
[9.5] 如何告诉编译器使一个成员函数成为内联函数?
声明内联成员函数看上去和普通函数非常类似:
class fred {
public:
void f(int i, char c);
};
但是当你定义内联成员函数时,在成员函数定义前加上 inline 关键字,并且将定义放入
头文件中。
inline
void fred::f(int i, char c)
{
// ...
}
通常将函数的定义({...}之间的部分)放在头文件中是强制的。如果你将内联函数的定义
放在 .cpp 文件中并且在其他 .cpp 文件中调用它,连接器将给出“unresolved external”
错误。
--------------------------------------------------------------------------------
[9.6] 有其它方法告诉编译器使成员函数成为内联吗?
有:在类体内定义成员函数:
class fred {
public:
void f(int i, char c)
{
// ...
}
};
尽管这对于写类的人来说很容易,但由于它将类是“什么”(what)和类“如何”(how)工作混
在一起,给阅读的人带来了困难。我们通常更愿意在类体外使用 inline 关键字定义成员函数
来避免这种混合。这种感觉所基于的认识是:在一个面向重用的世界中,使用你的类的人有很
多,而建造它的人只有一个(你自己);因此你做任何事都应该照顾多数而不是少数。
--------------------------------------------------------------------------------
[9.7] 内联函数保证执行的更好吗?
不。
小心过度使用内联函数可能导致代码膨胀。在页面调度环境中,它可能会给执行带来负面影响。
--------------------------------------------------------------------------------
revised sep 8, 1997
- 内联函数FAQ
- C++ FAQ阅读笔记[3]--内联函数
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- 函数内联
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- 内联函数
- string类模式匹配KMP 数组版本
- PHP文件操作详细诠释
- minicom配置
- alizee
- html的倒计时学习
- 内联函数FAQ
- VXLAN标准初探:扩展VLAN 支持远距离VM迁移
- 第13周任务2.1
- 今天开始在办公室上班了。
- 国外主要通用网络管理软件
- Netbeans7.0.1下使用JDBC连接MSSQL2008
- Java中的反射
- SQL Server自定义函数
- JNI:Java调用C/C++-传递空值(null)的处理方法