<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    注銷

    注銷

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      112 隨筆 :: 7 文章 :: 18 評論 :: 0 Trackbacks
    不同功能的函數其內部實現各不相同,看起來似乎無法就“內部實現”達成一致的觀點。但根據經驗,我們可以在函數體的“入口處”和“出口處”從嚴把關,從而提高函數的質量。
    ?
    l???????? 【規則6-3-1在函數體的“入口處”,對參數的有效性進行檢查。
    很多程序錯誤是由非法參數引起的,我們應該充分理解并正確使用“斷言”(assert)來防止此類錯誤。詳見6.5節“使用斷言”。
    ?
    l???????? 【規則6-3-2在函數體的“出口處”,對return語句的正確性和效率進行檢查。
    ?? ?如果函數有返回值,那么函數的“出口處”是return語句。我們不要輕視return語句。如果return語句寫得不好,函數要么出錯,要么效率低下。
    注意事項如下:
    (1)return語句不可返回指向“棧內存”的“指針”或者“引用”,因為該內存在函數體結束時被自動銷毀。例如
    ??? char * Func(void)
    ??? {
    ??????? char str[] = “hello world”; // str的內存位于棧上
    ???????
    ??? ?? return str;??????? // 將導致錯誤
    ??? }
    (2)要搞清楚返回的究竟是“值”、“指針”還是“引用”。
    (3)如果函數返回值是一個對象,要考慮return語句的效率。例如???
    ?????? ?????? return String(s1 + s2);
    這是臨時對象的語法,表示“創建一個臨時對象并返回它”。不要以為它與“先創建一個局部對象temp并返回它的結果”是等價的,如
    String temp(s1 + s2);
    return temp;
    實質不然,上述代碼將發生三件事。首先,temp對象被創建,同時完成初始化;然后拷貝構造函數把temp拷貝到保存返回值的外部存儲單元中;最后,temp在函數結束時被銷毀(調用析構函數)。然而“創建一個臨時對象并返回它”的過程是不同的,編譯器直接把臨時對象創建并初始化在外部存儲單元中,省去了拷貝和析構的化費,提高了效率。
    類似地,我們不要將?
    return int(x + y); // 創建一個臨時變量并返回它
    寫成
    int temp = x + y;
    return temp;
    由于內部數據類型如int,float,double的變量不存在構造函數與析構函數,雖然該“臨時變量的語法”不會提高多少效率,但是程序更加簡潔易讀。
    首先來看內部數據類型:
    return int(x+y)
    int temp = x+y;
    return temp;
    的區別:
    反匯編如下:
    ? 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 ?
    ?
    可見:對于前者編譯器直接將x+Y的值放如了寄存器eax中,而對于后者我們可以通過紅色反匯編部分,相對前者對復制了2次(從eaxàtemp,再從tempàeax).
    ?
    再看類類型
    return string (x+y)
    string temp = x+y;
    return temp;
    的區別:
    對于前者: 編譯器直接把臨時對象創建并初始化在外部存儲單元中,省去了拷貝和析構的化費,提高了效率
    ?
    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 對象 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對象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)//調用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臨時對象
    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對象destructor
    0040ED05?? mov???????? byte ptr [ebp-4],1
    0040ED09?? lea???????? ecx,[ebp-14h]
    0040ED0C?? call??????? @ILT+5(String::~String) (0040100a)//x對象destructor
    0040ED11?? mov???????? byte ptr [ebp-4],0
    0040ED15?? lea???????? ecx,[ebp-10h]
    0040ED18?? call??????? @ILT+5(String::~String) (0040100a) //destructor? 銷毀臨時對象
    0040ED1D?? mov???????? eax,dword ptr [ebp+8]
    144:????? };
    ?
    對于后者: 上述代碼將發生三件事。首先,temp對象被創建,同時完成初始化;然后拷貝構造函數把temp拷貝到保存返回值的外部存儲單元中;最后,temp在函數結束時被銷毀(調用析構函數)。
    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對象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對象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對象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)//調用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)??//調用operator=
    0040EE0E?? push??????? eax
    0040EE0F?? mov???????? ecx,dword ptr [ebp+8]
    0040EE12?? call??????? @ILT+15(String::String) (00401014) //constructor臨時對象
    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對象destructor
    0040EE2C?? mov???????? byte ptr [ebp-4],2
    0040EE30?? lea???????? ecx,[ebp-18h]
    0040EE33?? call??????? @ILT+5(String::~String) (0040100a)//y對象destructor
    0040EE38?? mov???????? byte ptr [ebp-4],1
    0040EE3C?? lea???????? ecx,[ebp-14h]
    0040EE3F?? call??????? @ILT+5(String::~String) (0040100a)//x對象destructor
    0040EE44?? mov???????? byte ptr [ebp-4],0
    0040EE48?? lea???????? ecx,[ebp-10h]
    0040EE4B?? call??????? @ILT+5(String::~String) (0040100a) //destructor銷毀臨時對象
    0040EE50?? mov???????? eax,dword ptr [ebp+8]
    145:?? ???};
    ?
    可見,兩中return方式都會有臨時對象的產生,而不同在于String temp; retrun temp=x+y方式多了三個步驟.(即紅色注釋), temp對象調用constructor, 調用operator=, temp對象調用destructor.所以說return String(x+y)效率比較高
    ?
    順便問大蝦們個問題 : 這段反匯編中 , 臨時對象是放在什么地方的呀 ??
    ?

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

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

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 无码人妻丰满熟妇区免费| 黄视频在线观看免费| 久久精品毛片免费观看| 亚洲av无码乱码国产精品| 国产精品福利片免费看| 精品亚洲视频在线观看| 中文在线观看免费网站| 亚洲综合另类小说色区| 国产羞羞的视频在线观看免费| 亚洲综合精品网站在线观看| 99久久99这里只有免费的精品 | jizz免费在线影视观看网站| 亚洲AV无码乱码精品国产| 九九全国免费视频| 亚洲熟伦熟女新五十路熟妇| 三上悠亚电影全集免费 | 亚洲成电影在线观看青青| **俄罗斯毛片免费| 亚洲视频免费播放| 日韩欧美一区二区三区免费观看| 亚洲午夜在线播放| 四虎影在线永久免费观看| 无遮挡呻吟娇喘视频免费播放| 亚洲精品成人网站在线观看 | 亚洲国产精品无码专区影院 | 久久亚洲熟女cc98cm| 国产91免费视频| 亚洲日韩精品国产一区二区三区| 国产成人无码区免费A∨视频网站 国产成人涩涩涩视频在线观看免费 | 亚洲第一区在线观看| 中文字幕无码一区二区免费| 亚洲天堂中文资源| 色吊丝最新永久免费观看网站| 一级毛片a女人刺激视频免费 | 亚洲人色婷婷成人网站在线观看 | 在线观看免费黄网站| 亚洲人成在线精品| 亚洲精品无码av天堂| 日本一卡精品视频免费 | 亚洲精品成人无限看| 日韩吃奶摸下AA片免费观看|