注銷

          注銷

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            112 隨筆 :: 7 文章 :: 18 評(píng)論 :: 0 Trackbacks
          不同功能的函數(shù)其內(nèi)部實(shí)現(xiàn)各不相同,看起來似乎無法就“內(nèi)部實(shí)現(xiàn)”達(dá)成一致的觀點(diǎn)。但根據(jù)經(jīng)驗(yàn),我們可以在函數(shù)體的“入口處”和“出口處”從嚴(yán)把關(guān),從而提高函數(shù)的質(zhì)量。
          ?
          l???????? 【規(guī)則6-3-1在函數(shù)體的“入口處”,對(duì)參數(shù)的有效性進(jìn)行檢查。
          很多程序錯(cuò)誤是由非法參數(shù)引起的,我們應(yīng)該充分理解并正確使用“斷言”(assert)來防止此類錯(cuò)誤。詳見6.5節(jié)“使用斷言”。
          ?
          l???????? 【規(guī)則6-3-2在函數(shù)體的“出口處”,對(duì)return語句的正確性和效率進(jìn)行檢查。
          ?? ?如果函數(shù)有返回值,那么函數(shù)的“出口處”是return語句。我們不要輕視r(shí)eturn語句。如果return語句寫得不好,函數(shù)要么出錯(cuò),要么效率低下。
          注意事項(xiàng)如下:
          (1)return語句不可返回指向“棧內(nèi)存”的“指針”或者“引用”,因?yàn)樵搩?nèi)存在函數(shù)體結(jié)束時(shí)被自動(dòng)銷毀。例如
          ??? char * Func(void)
          ??? {
          ??????? char str[] = “hello world”; // str的內(nèi)存位于棧上
          ???????
          ??? ?? return str;??????? // 將導(dǎo)致錯(cuò)誤
          ??? }
          (2)要搞清楚返回的究竟是“值”、“指針”還是“引用”。
          (3)如果函數(shù)返回值是一個(gè)對(duì)象,要考慮return語句的效率。例如???
          ?????? ?????? return String(s1 + s2);
          這是臨時(shí)對(duì)象的語法,表示“創(chuàng)建一個(gè)臨時(shí)對(duì)象并返回它”。不要以為它與“先創(chuàng)建一個(gè)局部對(duì)象temp并返回它的結(jié)果”是等價(jià)的,如
          String temp(s1 + s2);
          return temp;
          實(shí)質(zhì)不然,上述代碼將發(fā)生三件事。首先,temp對(duì)象被創(chuàng)建,同時(shí)完成初始化;然后拷貝構(gòu)造函數(shù)把temp拷貝到保存返回值的外部存儲(chǔ)單元中;最后,temp在函數(shù)結(jié)束時(shí)被銷毀(調(diào)用析構(gòu)函數(shù))。然而“創(chuàng)建一個(gè)臨時(shí)對(duì)象并返回它”的過程是不同的,編譯器直接把臨時(shí)對(duì)象創(chuàng)建并初始化在外部存儲(chǔ)單元中,省去了拷貝和析構(gòu)的化費(fèi),提高了效率。
          類似地,我們不要將?
          return int(x + y); // 創(chuàng)建一個(gè)臨時(shí)變量并返回它
          寫成
          int temp = x + y;
          return temp;
          由于內(nèi)部數(shù)據(jù)類型如int,float,double的變量不存在構(gòu)造函數(shù)與析構(gòu)函數(shù),雖然該“臨時(shí)變量的語法”不會(huì)提高多少效率,但是程序更加簡(jiǎn)潔易讀。
          首先來看內(nèi)部數(shù)據(jù)類型:
          return int(x+y)
          int temp = x+y;
          return temp;
          的區(qū)別:
          反匯編如下:
          ? return ? int(x+y); ? ? ? ? ? ? ? ? ? ? ? mov ? eax,x ?
          ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?add ? eax,y ?
          ? ?
          ? ?
          ? int ? temp ? = ? x ? + ? y; ? ? ? ? ??mov ? eax ? ,x ?
          ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??add ? eax ? ,y ?

          ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mov ? temp,eax ?
          ? ?
          ?
          return ? temp; ? ? ? ? ? ? ? ? ? ? ????? mov ? eax,temp ?
          ?
          可見:對(duì)于前者編譯器直接將x+Y的值放如了寄存器eax中,而對(duì)于后者我們可以通過紅色反匯編部分,相對(duì)前者對(duì)復(fù)制了2次(從eaxàtemp,再從tempàeax).
          ?
          再看類類型
          return string (x+y)
          string temp = x+y;
          return temp;
          的區(qū)別:
          對(duì)于前者: 編譯器直接把臨時(shí)對(duì)象創(chuàng)建并初始化在外部存儲(chǔ)單元中,省去了拷貝和析構(gòu)的化費(fèi),提高了效率
          ?
          138:????? String fun()
          139:????? {
          0040EC70?? push??????? ebp
          0040EC71?? mov???????? ebp,esp
          0040EC73?? push??????? 0FFh
          0040EC75?? push??????? offset __ehhandler$?fun@@YA?AVString@@XZ (004132f2)
          0040EC7A?? mov???????? eax,fs:[00000000]
          0040EC80?? push??????? eax
          0040EC81?? mov???????? dword ptr fs:[0],esp
          0040EC88?? sub???????? esp,58h
          0040EC8B?? push??????? ebx
          0040EC8C?? push??????? esi
          0040EC8D?? push???????edi
          0040EC8E?? lea???????? edi,[ebp-64h]
          0040EC91?? mov???????? ecx,16h
          0040EC96?? mov???????? eax,0CCCCCCCCh
          0040EC9B?? rep stos??? dword ptr [edi]
          0040EC9D?? mov???????? dword ptr [ebp-1Ch],0
          140:
          141:???????? String x;
          0040ECA4?? push??????? 0
          0040ECA6?? lea???????? ecx,[ebp-10h]
          0040ECA9?? call??????? @ILT+20(String::String) (00401019)
          //x 對(duì)象 constructor
          0040ECAE?? mov???????? dword ptr [ebp-4],1
          142:???????? String y;
          0040ECB5?? push??????? 0
          0040ECB7?? lea???????? ecx,[ebp-14h]
          0040ECBA?? call??? ????@ILT+20(String::String) (00401019)//y對(duì)象constructor
          0040ECBF?? mov???????? byte ptr [ebp-4],2
          143:???????? return String(x+y);
          0040ECC3?? lea???????? eax,[ebp-14h]
          0040ECC6?? push??????? eax
          0040ECC7?? lea???????? ecx,[ebp-10h]
          0040ECCA?? push??????? ecx
          0040ECCB?? lea???????? edx,[ebp-18h]
          0040ECCE?? push??????? edx
          0040ECCF?? call??????? @ILT+25(operator+) (0040101e)//調(diào)用operator+
          0040ECD4?? add???????? esp,0Ch
          0040ECD7?? mov???????? dword ptr [ebp-20h],eax
          0040ECDA?? mov???????? eax,dword ptr [ebp-20h]
          0040ECDD?? mov???????? dword ptr [ebp-24h],eax
          0040ECE0?? mov???????? byte ptr [ebp-4],3
          0040ECE4?? mov???????? ecx,dword ptr [ebp-24h]
          0040ECE7?? push??????? ecx
          0040ECE8?? mov???????? ecx,dword ptr [ebp+8]
          0040ECEB?? call??????? @ILT+15(String::String) (00401014) //constructor臨時(shí)對(duì)象
          0040ECF0?? mov???????? edx,dword ptr [ebp-1Ch]
          0040ECF3?? or????????? edx,1
          0040ECF6?? mov???????? dword ptr [ebp-1Ch],edx
          0040ECF9?? mov???????? byte ptr [ebp-4],2
          0040ECFD?? lea??????? ?ecx,[ebp-18h]
          0040ED00?? call??????? @ILT+5(String::~String) (0040100a)//y對(duì)象destructor
          0040ED05?? mov???????? byte ptr [ebp-4],1
          0040ED09?? lea???????? ecx,[ebp-14h]
          0040ED0C?? call??????? @ILT+5(String::~String) (0040100a)//x對(duì)象destructor
          0040ED11?? mov???????? byte ptr [ebp-4],0
          0040ED15?? lea???????? ecx,[ebp-10h]
          0040ED18?? call??????? @ILT+5(String::~String) (0040100a) //destructor? 銷毀臨時(shí)對(duì)象
          0040ED1D?? mov???????? eax,dword ptr [ebp+8]
          144:????? };
          ?
          對(duì)于后者: 上述代碼將發(fā)生三件事。首先,temp對(duì)象被創(chuàng)建,同時(shí)完成初始化;然后拷貝構(gòu)造函數(shù)把temp拷貝到保存返回值的外部存儲(chǔ)單元中;最后,temp在函數(shù)結(jié)束時(shí)被銷毀(調(diào)用析構(gòu)函數(shù))。
          138:????? String fun()
          139:????? {
          0040ED80?? push??????? ebp
          0040ED81?? mov???????? ebp,esp
          0040ED83?? push??????? 0FFh
          0040ED85?? push??????? offset __ehhandler$?fun@@YA?AVString@@XZ (004132fb)
          0040ED8A?? mov???????? eax,fs:[00000000]
          0040ED90?? push??????? eax
          0040ED91?? mov???????? dword ptr fs:[0],esp
          0040ED98?? sub???????? esp,5Ch
          0040ED9B?? push??????? ebx
          0040ED9C?? push??????? esi
          0040ED9D?? push??????? edi
          0040ED9E?? lea???????? edi,[ebp-68h]
          0040EDA1?? mov???????? ecx,17h
          0040EDA6?? mov???????? eax,0CCCCCCCCh
          0040EDAB?? rep stos??? dword ptr [edi]
          0040EDAD?? mov???????? dword ptr [ebp-20h],0
          140:
          141:???????? String x;
          0040EDB4?? push??????? 0
          0040EDB6?? lea???????? ecx,[ebp-10h]
          0040EDB9?? call??????? @ILT+20(String::String) (00401019)//x對(duì)象constructor
          0040EDBE?? mov???????? dword ptr [ebp-4],1
          142:???????? String y;
          0040EDC5?? push??????? 0
          0040EDC7?? lea???????? ecx,[ebp-14h]
          0040EDCA?? call??????? @ILT+20(String::String) (00401019)?//y對(duì)象constructor
          ?
          0040EDCF?? mov???????? byte ptr [ebp-4],2
          143:???????? String temp;
          0040EDD3?? push??????? 0
          0040EDD5?? lea???????? ecx,[ebp-18h]
          0040EDD8?? call??????? @ILT+20(String::String) (00401019)//temp對(duì)象constructor
          0040EDDD?? mov???????? byte ptr [ebp-4],3
          144:???????? return temp=x+y;
          0040EDE1?? lea???????? eax,[ebp-14h]
          0040EDE4?? push??????? eax
          0040EDE5?? lea???????? ecx,[ebp-10h]
          0040EDE8?? push??????? ecx
          0040EDE9?? lea???????? edx,[ebp-1Ch]
          0040EDEC?? push??????? edx
          0040EDED?? call??????? @ILT+25(operator+) (0040101e)//調(diào)用operator+
          0040EDF2?? add???????? esp,0Ch
          0040EDF5?? mov???????? dword ptr [ebp-24h],eax
          0040EDF8?? mov???????? eax,dword ptr [ebp-24h]
          0040EDFB?? mov???????? dword ptr [ebp-28h],eax
          0040EDFE?? mov???????? byte ptr [ebp-4],4
          0040EE02?? mov???????? ecx,dword ptr [ebp-28h]
          0040EE05?? push??????? ecx
          0040EE06?? lea???????? ecx,[ebp-18h]
          0040EE09?? call??????? @ILT+0(String::operator=) (00401005)??//調(diào)用operator=
          0040EE0E?? push??????? eax
          0040EE0F?? mov???????? ecx,dword ptr [ebp+8]
          0040EE12?? call??????? @ILT+15(String::String) (00401014) //constructor臨時(shí)對(duì)象
          0040EE17?? mov???????? edx,dword ptr [ebp-20h]
          0040EE1A?? or????????? edx,1
          0040EE1D?? mov???????? dword ptr [ebp-20h],edx
          0040EE20?? mov???????? byte ptr [ebp-4],3
          0040EE24?? lea???????? ecx,[ebp-1Ch]
          0040EE27?? call??????? @ILT+5(String::~String) (0040100a)//temp對(duì)象destructor
          0040EE2C?? mov???????? byte ptr [ebp-4],2
          0040EE30?? lea???????? ecx,[ebp-18h]
          0040EE33?? call??????? @ILT+5(String::~String) (0040100a)//y對(duì)象destructor
          0040EE38?? mov???????? byte ptr [ebp-4],1
          0040EE3C?? lea???????? ecx,[ebp-14h]
          0040EE3F?? call??????? @ILT+5(String::~String) (0040100a)//x對(duì)象destructor
          0040EE44?? mov???????? byte ptr [ebp-4],0
          0040EE48?? lea???????? ecx,[ebp-10h]
          0040EE4B?? call??????? @ILT+5(String::~String) (0040100a) //destructor銷毀臨時(shí)對(duì)象
          0040EE50?? mov???????? eax,dword ptr [ebp+8]
          145:?? ???};
          ?
          可見,兩中return方式都會(huì)有臨時(shí)對(duì)象的產(chǎn)生,而不同在于String temp; retrun temp=x+y方式多了三個(gè)步驟.(即紅色注釋), temp對(duì)象調(diào)用constructor, 調(diào)用operator=, temp對(duì)象調(diào)用destructor.所以說return String(x+y)效率比較高
          ?
          順便問大蝦們個(gè)問題 : 這段反匯編中 , 臨時(shí)對(duì)象是放在什么地方的呀 ??
          ?

          Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1394353

          posted on 2006-11-19 10:09 注銷..... 閱讀(230) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 克东县| 清镇市| 托克逊县| 黄浦区| 从江县| 瓦房店市| 旺苍县| 行唐县| 隆化县| 大同县| 体育| 天峨县| 鄱阳县| 秦皇岛市| 临沧市| 衡阳市| 丰县| 永寿县| 潜江市| 南投市| 河南省| 永靖县| 永嘉县| 利川市| 昆明市| 行唐县| 肇州县| 长沙县| 钟祥市| 岗巴县| 灵台县| 西贡区| 定兴县| 徐水县| 石景山区| 鲁甸县| 黔西县| 武夷山市| 漯河市| 阜南县| 鄯善县|