转载水木
误解: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理论上也是
可以展开的。