轉載水木
誤解:inline函數沒有單獨的函數體,也不能取地址。
inline修飾并不會改變函數的通常語義,仍可通過函數指針調用:
inline?void?f()?{}
void?g()?{
??void?(*p)()?=?f;
??p();
}
------------------------------------------------------------------------
誤解:inline一定導致代碼膨脹
class?Foo?{
public:
????????int?Bar()?{?return?foo;?}
private:
????????int?foo;
};
這樣的Foo::Bar?inline會讓binary變小
------------------------------------------------------------------------
誤解:?inline函數一定是internal?linkage/no?linkage的。
inline與函數的linkage無關。inline函數同樣可以用static和extern修飾,并具
備同一般函數相同的linkage。標準要求external?linkage的inline函數在所有編
譯單元中具有相同的地址。external?linkage的inline函數內定義的靜態變量同
樣應在所有編譯單元中表現為單一對象,具有相同的地址。
------------------------------------------------------------------------
誤解:?如果inline函數包含循環/調用了其他函數/遞歸調用自己,編譯器就無法
??????將其展開。
某些早期的編譯器有這類限制,但對現代編譯器來說它們不再是inline展開的障
礙了。
[insert?RoachCock's?example?here]
------------------------------------------------------------------------
誤解:inline和virtual不能同時修飾一個函數。
inline和virtual并不沖突。以下程序編譯通過。
#include?<iostream>
struct?A
{
??inline?virtual?void?f()
??{
????std::cout?<<?"inline?virtual"?<<?std::endl;
??}
};
------------------------------------------------------------------------
誤解:virtual函數即使聲明為inline,由于是late?binding,無法判斷實際
??????調用的版本,編譯器也無法展開。
虛函數調用并不總是late?binding。
示例:
struct?Base
{
??virtual?void?foo(){cout?<<?"Base::foo"?<<?endl;}
};
struct?Derived?:?Base
{
??void?foo(){cout?<<?"Derived::foo"?<<?endl;}
};
void?bar(Base&?b)
{
??b.foo();??//?late?binding.?if?b?is?a?Derived,?call?Derived::foo
??b.Base::foo();??//?early?binding.?inline
??Derived?d;
??d.foo();??//?early?binding.?inline
}
另外,盡管在您的編譯器中很可能還沒有實現,但即使late?binding理論上也是
可以展開的。