是不是在类定义中被定义的成员函数会被自动当作是内联函数?或者在定义成员函数时显式地添加inline关键字,该函数就会被定义成内联的呢?
实际上不是!对于编译器来说,内联函数是一种请求,而不是一种保证(C++ Primer(3Ed) P26)。
下面以在VC++7.0下产生的代码为例。
// inline内联函数演示
// InlineDemo.h
#pragma once
#include <iostream>
using namespace std;
{
public:
// inline?
InLine() { cout << "InLine Construct!" << endl;}
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
在这种情况下,所有成员函数都被编译为非内联的。