构造函数、析构函数、虚函数可否内联,有何意义

在语法上没有错误

首先要掌握一点,构造函数、析构函数、虚函数可以声明为内联函数,这在语法上是正确的。

如下面代码是正确的,因为inline同register一样,只是个建议,编译器并不一定真正的内联,在语法上是没有错误的

1
2
3
4
5
6
7
8
9
10
11
12

class A
{
public:
    inline A() {}
    inline ~A() {}
    inline virtual void  virtualFun() {}
};
 
int main()
{
    return 0;
}

将构造函数和析构函数声明为inline是没有什么意义的

需要思考的是构造函数、析构函数、虚函数被声明为inline有意义吗,或者说编译器是否对这些函数真正内联呢?

先来看构造函数和析构函数,参阅Effective C++得知,将构造函数和析构函数声明为inline是没有什么意义的,即编译器并不真正对声明为inline的构造和析构函数内联,因为编译器会在构造和析构函数中添加额外的操作(申请/释放内存,构造/析构对象等),致使构造函数/析构函数并不像看上去的那么精简

 

将虚函数声明为inline,要分情况讨论

有的人认为虚函数被声明为inline,但是编译器并没有对其内联,他们给出的理由是inline是编译期决定的,而虚函数是运行期决定的,即在不知道将要调用哪个函数的情况下,如何将函数内联呢?

 

上述观点看似正确,其实不然,如果虚函数在编译器就能够决定将要调用哪个函数时,就能够内联,那么什么情况下编译器可以确定要调用哪个函数呢,答案是当用对象调用虚函数时,就内联展开。

 

综上,当是指向派生类的指针调用声明为inline的虚函数时,不会内联展开;当是对象调用虚函数时,会内联展开。

 

When the object is referenced via a pointer or a reference, a call to a virtual function cannot be inlined, since the call must be resolved dynamically. Reason: the compiler can't know which actual code to call until run-time (i.e., dynamically), since the code may be from a derived class that was created after the caller was compiled.

Therefore the only time an inline virtual call can be inlined is when the compiler knows the "exact class" of the object which is the target of the virtual function call. This can happen only when the compiler has an actual object rather than a pointer or reference to an object. I.e., either with a local object, a global/static object, or a fully contained object inside a composite.

posted @ 2013-06-14 20:18  helloweworld  阅读(2818)  评论(0编辑  收藏  举报