📄 [9] inline functions, c++ faq lite.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<!-- saved from url=(0054)http://www.sunistudio.com/cppfaq/inline-functions.html -->
<HTML><HEAD><TITLE>[9] Inline functions, C++ FAQ Lite</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META http-equiv=Content-Language content=zh-cn>
<META content=inline-functions.html name=FILENAME>
<META content="[9] Inline functions, C++ FAQ Lite" name=ABSTRACT>
<META content=cline@parashift.com name=OWNER>
<META content="Marshall Cline, cline@parashift.com" name=AUTHOR>
<META content="MSHTML 6.00.2462.0" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId><LINK rev=made
href="mailto:cline@parashift.com"><LINK
href="[9] Inline functions, C++ FAQ Lite.files/cpp-faq.css" type=text/css
rel=stylesheet></HEAD>
<BODY>
<H1><A name=top></A>[9] 内联函数<BR><SMALL><SMALL>(Part of <A
href="http://www.sunistudio.com/cppfaq/index.html"><EM>C++ FAQ Lite</EM></A>, <A
href="http://www.sunistudio.com/cppfaq/copy-permissions.html#[1.2]">Copyright ©
1991-2001</A>, <A href="http://www.parashift.com/" target=OutsideTheFAQ>Marshall
Cline</A>, <A
href="mailto:cline@parashift.com">cline@parashift.com</A>)</SMALL></SMALL></H1>
<P>简体中文版翻译:<A href="http://www.sunistudio.com/nicrosoft">申旻</A>,<A
href="mailto:nicrosoft@sunistudio.com">nicrosoft@sunistudio.com</A>(<A
href="http://www.sunistudio.com/">东日制作室</A>,<A
href="http://www.sunistudio.com/asp/sunidoc.asp">东日文档</A>)</P>
<HR>
<H3>FAQs in section [9]:</H3>
<UL>
<LI><A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#[9.1]">[9.1]
内联函数是什么?</A>
<LI><A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#[9.2]">[9.2]
内联函数是如何在安全和速度上取得折衷?</A>
<LI><A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#[9.3]">[9.3]
为什么我应该用内联函数?而不是原来清晰的 #define 宏?</A> <IMG alt=UPDATED!
src="[9] Inline functions, C++ FAQ Lite.files/updated.gif">
<LI><A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#[9.4]">[9.4]
如何告诉编译器使非成员函数成为内联函数?</A>
<LI><A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#[9.5]">[9.5]
如何告诉编译器使一个成员函数成为内联函数?</A>
<LI><A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#[9.6]">[9.6]
有其它方法告诉编译器使成员函数成为内联吗?</A>
<LI><A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#[9.7]">[9.7]
内联函数保证执行性能更好吗?</A> <IMG alt=UPDATED!
src="[9] Inline functions, C++ FAQ Lite.files/updated.gif"> </LI></UL>
<P>
<HR>
<P><A name=[9.1]></A>
<DIV class=FaqTitle>
<H3>[9.1] 内联函数是什么?</H3></DIV>
<P>内联函数是代码被插入到调用者代码串处的函数。如同 #define 宏,内联函数通过避免被调用的开销来提高执行效率,尤其是它能够通过调用(“过程化集成”)被编译器优化。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/references.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/ctors.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[9.2]></A>
<DIV class=FaqTitle>
<H3>[9.2] 内联函数是如何在安全和速度上取得折衷?</H3></DIV>
<P>在 C 中,你可以通过在结构中设置一个 <TT>void*</TT> 来得到“封装的结构”,在这种情况下,指向实际数据的 <TT>void*</TT> 指针对于结构的用户来说是未知的。因此结构的用户不知道如何解释<TT>void*</TT>指针所指内容,但是存取函数可以将 <TT>void*</TT> 转换成适当的隐含类型。这样给出了封装的一种形式。<BR><BR>不幸的是这样做丧失了类型安全,并且也将繁琐的对结构中的每个域的访问强加于函数调用。(如果你允许直接存取结构的域,那么对任何能直接存取的人来说,了解如何解释 <TT>void*</TT> 指针所指内容就是必要的了;这样将使改变底层数据结构变的困难)。<BR><BR>虽然函数调用开销是很小的,但它会被累积。C++类允许函数调用以内联展开。这样让你在得到封装的安全性时,同时得到直接存取的速度。此外,内联函数的参数类型由编译器检查,这是对 C 的 <TT>#define</TT> 宏的一个改进。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/references.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/ctors.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[9.3]></A>
<DIV class=FaqTitle>
<H3>[9.3] 为什么我应该用内联函数?而不是原来清晰的 #define 宏? <IMG alt=UPDATED!
src="[9] Inline functions, C++ FAQ Lite.files/updated.gif"></H3></DIV><SMALL><EM>[Recently
rewrote the sentence on <TT>#define</TT> being evil (on 7/00). <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#[9.7]">Click here
to go to the next FAQ in the "chain" of recent changes<!--rawtext:[9.7]:rawtext--></A>.]</EM></SMALL>
<P>因为<TT>#define</TT>宏是在四处是有害的:<A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#[9.3]">罪状#1<!--rawtext:[9.3]:rawtext--></A>,
<A
href="http://www.sunistudio.com/cppfaq/misc-technical-issues.html#[34.1]">罪状#2<!--rawtext:[34.1]:rawtext--></A>,
<A
href="http://www.sunistudio.com/cppfaq/misc-technical-issues.html#[34.2]">罪状#3<!--rawtext:[34.2]:rawtext--></A>,
和 <A
href="http://www.sunistudio.com/cppfaq/misc-technical-issues.html#[34.3]">罪状</A><A
href="http://www.sunistudio.com/cppfaq/misc-technical-issues.html#[34.3]">#4<!--rawtext:[34.3]:rawtext--></A>。
<P>和 #define 宏不同的是,内联函数总是对参数只精确地进行一次求值,从而避免了声名狼藉的宏错误。换句话说,调用内联函数和调用正规函数是等价的,差别仅仅是更快:<BR>
<DIV class=CodeBlock><TT> </TT><EM>// </EM>返回
<TT>i</TT> 的绝对值的宏<TT><BR> #define unsafe(i) \<BR> ( (i) >= 0 ? (i) : -(i) )<BR> <BR> </TT><EM>// </EM>返回 <TT>i
</TT>的绝对值的内联函数<TT><BR> inline<BR> int safe(int i)<BR> {<BR> return i >= 0 ? i : -i;<BR> }<BR> <BR> int f();<BR> <BR> void userCode(int x)<BR> {<BR> int ans;<BR> <BR> ans = unsafe(x++); </TT><EM>// 错误!x 被增加两次</EM><TT><BR> ans = unsafe(f()); </TT><EM>// 危险!f()被调用两次</EM><TT><BR> <BR> ans = safe(x++); </TT><EM>// 正确! x 被增加一次</EM><TT><BR> ans = safe(f()); </TT><EM>// 正确! f() 被调用一次</EM><TT><BR> }
</TT></DIV>
<P>和宏不同的,还有内联函数的参数类型被检查,并且被正确地进行必要的转换。<BR><BR>宏是有害的;非万不得已不要用。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/references.html">Previous section</A>
| <A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -