现在的位置: 首页 > 综合 > 正文

关于inline

2012年01月31日 ⁄ 综合 ⁄ 共 8109字 ⁄ 字号 评论关闭

是不是在类定义中被定义的成员函数会被自动当作是内联函数?或者在定义成员函数时显式地添加inline关键字,该函数就会被定义成内联的呢?
实际上不是!对于编译器来说,内联函数是一种请求,而不是一种保证(C++ Primer(3Ed) P26)。
下面以在VC++7.0下产生的代码为例。
// inline内联函数演示
// InlineDemo.h

#pragma once

#include <iostream>

using namespace std;

class InLine
{
public: 
 // inline?
 InLine() { cout << "InLine Construct!" << endl;}
//  inline?
 void setAB(int a , int b) {this->a = a;this->b = b;}
 int getA();
 int getB();
protected:
 int a , b;
};

// inline?
inline int InLine::getA()
{
 return a;
}

// non-inline?
int InLine::getB()
{
 return b;
}

// InlineDemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "InlineDemo.h"

int _tmain(int argc, _TCHAR* argv[])
{
 InLine inlinea;

 inlinea.setAB(10 , 12);

 cout << inlinea.getA() << endl;

 cout << inlinea.getB() << endl;

 return 0;
}

选项/0b1(内联函数展开中的“只适合用于__inline”)打开后的反汇编代码:
.text:004012D0 _main           proc near               ; CODE XREF: j__mainj
.text:004012D0
.text:004012D0 var_58          = dword ptr -58h
.text:004012D0 var_40          = dword ptr -40h
.text:004012D0 var_28          = dword ptr -28h
.text:004012D0 var_C           = dword ptr -0Ch
.text:004012D0 var_8           = dword ptr -8
.text:004012D0
.text:004012D0                 push    ebp
.text:004012D1                 mov     ebp, esp
.text:004012D3                 sub     esp, 58h
.text:004012D6                 push    edi
.text:004012D7                 lea     edi, [ebp+var_58]
.text:004012DA                 mov     ecx, 16h
.text:004012DF                 mov     eax, 0CCCCCCCCh
.text:004012E4                 rep stosd
.text:004012E6                 push    offset
??_C@_0BC@FJCDLOJM@InLine?5Construct?$CB?$AA@ ; "InLine Construct!" 被编译成内联的
.text:004012EB                 push    offset std__cout
.text:004012F0                 call   
j_??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z
.text:004012F5                 add     esp, 8
.text:004012F8                 mov     [ebp+var_28], eax
.text:004012FB                 push    0Ah
.text:004012FD                 mov     ecx, [ebp+var_28]
.text:00401300                 call   
j_?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char>>::put(char)
.text:00401305                 mov     ecx, [ebp+var_28]
.text:00401308                 call   
j_?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ ; std::basic_ostream<char,std::char_traits<char>>::flush(void),自此构造函数输出"InLine Construct!"完成
.text:0040130D                 mov     [ebp+var_C], 0Ah     ;InLine::setAB(10 , 12)开始

.text:00401314                 mov     [ebp+var_8], 0Ch      ;InLine::setAB(10 , 12)结束
.text:0040131B                 mov     eax, [ebp+var_C]
.text:0040131E                 push    eax
.text:0040131F                 mov     ecx, offset std__cout
.text:00401324                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
.text:00401329                 mov     [ebp+var_40], eax    ;InLine::getA()被展开
.text:0040132C                 push    0Ah
.text:0040132E                 mov     ecx, [ebp+var_40]
.text:00401331                 call   
j_?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char>>::put(char)
.text:00401336                 mov     ecx, [ebp+var_40]
.text:00401339                 call   
j_?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ ; std::basic_ostream<char,std::char_traits<char>>::flush(void)
.text:0040133E                 lea     ecx, [ebp+var_C]
.text:00401341                 call   
j_?getB@InLine@@QAEHXZ ; InLine::getB(void)为非内联
.text:00401346                 push    eax
.text:00401347                 mov     ecx, offset std__cout
.text:0040134C                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
.text:00401351                 mov     [ebp+var_58], eax
.text:00401354                 push    0Ah
.text:00401356                 mov     ecx, [ebp+var_58]
.text:00401359                 call   
j_?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char>>::put(char)
.text:0040135E                 mov     ecx, [ebp+var_58]
.text:00401361                 call   
j_?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ ; std::basic_ostream<char,std::char_traits<char>>::flush(void)
.text:00401366                 xor     eax, eax
.text:00401368                 push    edx
.text:00401369                 mov     ecx, ebp
.text:0040136B                 push    eax
.text:0040136C                 lea     edx, dword_401388
.text:00401372                 call    _RTC_CheckStackVars
.text:00401377                 pop     eax
.text:00401378                 pop     edx
.text:00401379                 pop     edi
.text:0040137A                 add     esp, 58h
.text:0040137D                 cmp     ebp, esp
.text:0040137F                 call    _RTC_CheckEsp
.text:00401384                 mov     esp, ebp
.text:00401386                 pop     ebp
.text:00401387                 retn
.text:00401387 _main           endp
在这种情况下,上面两个问题的回答是肯定的。
该选项未未打开是的反汇编代码:
.text:004015D0 _main           proc near               ; CODE XREF: j__mainj
.text:004015D0
.text:004015D0 var_10          = dword ptr -10h
.text:004015D0 var_C           = dword ptr -0Ch
.text:004015D0 var_8           = dword ptr -8
.text:004015D0 var_4           = dword ptr -4
.text:004015D0
.text:004015D0                 push    ebp
.text:004015D1                 mov     ebp, esp
.text:004015D3                 sub     esp, 10h
.text:004015D6                 mov     eax, 0CCCCCCCCh
.text:004015DB                 mov     [ebp+var_10], eax
.text:004015DE                 mov     [ebp+var_C], eax
.text:004015E1                 mov     [ebp+var_8], eax
.text:004015E4                 mov     [ebp+var_4], eax
.text:004015E7                 lea     ecx, [ebp+var_C]
.text:004015EA                 call   
j_??0InLine@@QAE@XZ ; InLine::InLine(void)
.text:004015EF                 push    0Ch
.text:004015F1                 push    0Ah
.text:004015F3                 lea     ecx, [ebp+var_C]
.text:004015F6                 call   
j_?setAB@InLine@@QAEXHH@Z ; InLine::setAB(int,int)
.text:004015FB                 push    offset loc_4010B4
.text:00401600                 lea     ecx, [ebp+var_C]
.text:00401603                 call   
j_?getA@InLine@@QAEHXZ ; InLine::getA(void)
.text:00401608                 push    eax
.text:00401609                 mov     ecx, offset std__cout
.text:0040160E                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
.text:00401613                 mov     ecx, eax
.text:00401615                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))
.text:0040161A                 push    offset loc_4010B4
.text:0040161F                 lea     ecx, [ebp+var_C]
.text:00401622                 call   
j_?getB@InLine@@QAEHXZ ; InLine::getB(void)
.text:00401627                 push    eax
.text:00401628                 mov     ecx, offset std__cout
.text:0040162D                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
.text:00401632                 mov     ecx, eax
.text:00401634                 call   
j_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))
.text:00401639                 xor     eax, eax
.text:0040163B                 push    edx
.text:0040163C                 mov     ecx, ebp
.text:0040163E                 push    eax
.text:0040163F                 lea     edx, dword_40165A
.text:00401645                 call    _RTC_CheckStackVars
.text:0040164A                 pop     eax
.text:0040164B                 pop     edx
.text:0040164C                 add     esp, 10h
.text:0040164F                 cmp     ebp, esp
.text:00401651                 call    _RTC_CheckEsp
.text:00401656                 mov     esp, ebp
.text:00401658                 pop     ebp
.text:00401659                 retn
.text:00401659 _main           endp
在这种情况下,所有成员函数都被编译为非内联的。

抱歉!评论已关闭.