内联函数
Table of Contents
摘抄自C++ FAQ Lite的内联函数笔记:
转载说明
本文摘抄自C++ FAQ Lite中文版
版权声明: Part of C++ FAQ Lite, Copyright © 1991-2001, Marshall Cline, cline@parashift.com
[9.6] 如何告诉编译器使非成员函数成为内联函数?
声明内联函数看上去和普通函数非常相似:
void f(int i, char c);
当你定义一个内联函数时,在函数定义前加上 inline 关键字,并且将定义放入头文件:
inline void f(int i, char c) { // … }
注意:将函数的定义({…}之间的部分)放在头文件中是强制的,除非该函数仅仅被单个 .cpp 文件使用。尤其是,如果你将内联函数的定义放在 .cpp 文件中并且在其他 .cpp文件中调用它,连接器将给出 “unresolved external” 错误。
[9.7] 如何告诉编译器使一个成员函数成为内联函数?
声明内联成员函数看上去和普通成员函数非常类似:
class Fred { public: void f(int i, char c); };
但是当你定义内联成员函数时,在成员函数定义前加上 inline 关键字,并且将定义放入头文件中:
inline void Fred::f(int i, char c) { // … }
通常将函数的定义({…}之间的部分)放在头文件中是强制的,除非函数只在一个.cpp文件中用到。特别是,如果你将内联函数的定义放在 .cpp 文件中并且在其他 .cpp 文件中调用它,连接器将给出 “unresolved external”错误。
[9.8] 有其它方法告诉编译器使成员函数成为内联吗?
有:在类体内定义成员函数:
class Fred { public: void f(int i, char c) { // … } };
尽管这对于写类的人来说很容易,但由于它将类是“什么”(what)和类“如何”(how)工作混在一起,给阅读的人带来了困难。我们通常更愿意在类体外使用 inline 关键字定义成员函数来避免这种混合。这种感觉所基于的认识是:在一个面向重用的世界中,使用你的类的人有很多,而编写它的人只有一个(你自己);因此你做任何事都应该照顾多数而不是少数。下一条FAQ进一步应用了这个方法。
[9.9] 在定义于类外部的内联函数中,以下哪种方法最好:是把inline关键字放在类内部的成员函数声明前呢,还是放到类外部函数的定义前呢,还是两个地方都写?
最佳实践是:仅放在类外部函数的定义前。
class Foo { public: void method(); ← best practice: don't put the inline keyword here … };
inline void Foo::method() ← best practice: put the inline keyword here { … }
这里是基本的想法:
- 类的public部分是你描述类的可见语义的地方,包含公有成员函数、友元函数和任何其它暴露给外部的内容。不要提供在调用者代码中看不到的细节。
- 类的其它部分,包括非公有部分、成员定义和友元函数声明等等,这些纯粹是实现细节。如果还没有在类的公有部分描述,那么不要提供相关可见语义。
从一种实际的观点来看,这种隔离能够使用户更轻松和更安全。假设Chuck只是想“用”你的类。因为你读了本FAQ并使用了上述隔离办法,Chuck能够在类的公有部分找到所有需要的内容,而不必看任何不需要的内容。他能够更加轻松,因为只需要看一个地方。同时也会更安全,因为他纯洁的思想不必受到实现细节的干扰。
回到内联上来:一个函数是否内联只是实现细节,不会改变函数调用的可见语义(即含义)。因此inline关键字应该和函数定义放在一起,而不是在类的public声明区。
注意:大部分人使用“声明”和“定义”来区分以上所述的两个位置。例如,人们会说“我应该把inline关键字放到声明那里还是放在定义那里?”但这种说法不太严密,可能会有人因此笑话你。笑话你的人可能只是不自信而又装腔作势的可怜虫,他们无法在其生命中取得一些成就。然而,你还是可以学会使用正确的术语来避免被笑话。其实,每个定义同时也是声明。也就是说,如果把这两者当作是互斥的,那么就好像是在问钢和金属哪个更重。当你把“定义”说成是“声明”的对立面时,几乎所有人都都明白你的意思。只有最糟糕的痴迷于技术的小人物才会因此嘲笑你。但至少你知道如何正确使用术语。
Date: 2010-10-12 16:06:34 CST
HTML generated by org-mode TAG=7.01g in emacs 23