天天看點

【No.16 異常的直接插入排序】

==【注意】== 程式語言隻是我們與計算機交流并讓計算機實作我們創造性思想的工具,可以并鼓勵深入掌握一門語言,但千萬别沉迷于鑽某種語言的牛角尖,一定要把握好二者間的度

本帖屬不定時連載貼,以試卷的形式提出一個比較基礎的問題供大家思考讨論,問題的解析将在下一更新貼中一并給出,這樣做是希望還不清楚問題的朋友有自己思考和讨論的時間,希望大家能從這些文章中有所收獲。

貼中問題屬我在學習C\C++過程中遇到的一些文法或者比較隐晦的程式問題,其中有自己的總結,也不乏網絡上搜尋到的經典解析,在此分享給大家,希望能起到抛磚引玉的作用

【No.16 異常的直接插入排序】

由于連載形式,每帖第二部分都配有上一問題的解答。為了保持文章的針對性和一緻性,此貼僅供交流讨論本次問題,若大家對上一問題有任何疑問,請通過解答末尾的傳送連結前往該問題貼回複讨論

[問題No.16]

下面的直接插入排序邏輯沒有問題,但為什麼無法正确運作呢?

複制内容到剪貼闆

<code>void insertSort(int *arr, const size_t arrLength){   for(size_t i=1; i&lt;arrLength; ++i){     int elemToInsert = arr;     size_t j = 0;     for(j=i-1; j&gt;=0; --j){       if(arr[j] &gt; elemToInsert)         arr[j+1] = arr[j];       else         break;     }     arr[j+1] = elemToInsert;   } }</code>

本主題主要是向大家提出對象“自指派”的問題,以引起大家的重視。這是個經典的問題,我們在編寫指派操作符時,既要具有自指派安全性(即自指派不應該改變原對象的狀态),也應該具有異常安全性。下面的代碼對這一問題進行了簡要闡釋,希望尚不知道的午飯引起重視。

<code>#include&lt;iostream&gt; #include&lt;string&gt; using std::cout; using std::endl; using std::string; #define WITHOUT_IDENTITY_TEST  //沒有對自指派做檢測 //#define IDENTITY_TEST  //有自指派檢測,但沒有異常安全 //#define SAVING_ORIGIN_POINTER  //提供異常安全,并順帶提供了自指派檢測 //#define COPY_AND_SWAP  //一種被稱為copy and swap的技術提供異常安全,并順帶提供自指派檢測 class Foo {   public:     Foo(const string str) : _str(new string(str)){ }     Foo(const Foo &amp;foo){ _str = new string(*foo._str); }     ~Foo(void){ delete _str; } #ifdef WITHOUT_IDENTITY_TEST     //沒有對自指派做檢測     Foo&amp; operator =(const Foo &amp;foo){       delete _str;       _str = new string(*foo._str);       return *this;     } #endif #ifdef IDENTITY_TEST     //有自指派檢測,但沒有異常安全     Foo&amp; operator =(const Foo &amp;foo){       if(this == &amp;foo)         return *this;       delete _str;       _str = new string(*foo._str);       return *this;     } #endif #ifdef SAVING_ORIGIN_POINTER     //提供異常安全,并順帶提供了自指派檢測     Foo&amp; operator =(const Foo &amp;foo){       string *original = _str;       _str = new string(*foo._str);       return *this;     } #endif #ifdef COPY_AND_SWAP     //一種被稱為copy and swap的技術提供異常安全,并順帶提供自指派檢測     Foo&amp; operator =(const Foo &amp;foo){       Foo temp(foo);       _swap(temp);       return *this;     } #endif     const string&amp; getStr(void) const { return *_str; }   private:     void _swap(Foo &amp;foo){       string temp = *_str;       *_str = *foo._str;       *foo._str = temp;     }     string *_str; }; int main(int argc, char **argv) {   Foo f1("first"), f2("second");   cout&lt;&lt;"f1 = "&lt;&lt;f1.getStr()&lt;&lt;"\tf2 = "&lt;&lt;f2.getStr()&lt;&lt;endl;   f1 = f2;   cout&lt;&lt;"f1 = "&lt;&lt;f1.getStr()&lt;&lt;"\tf2 = "&lt;&lt;f2.getStr()&lt;&lt;endl;   f1 = f1;   cout&lt;&lt;"f1 = "&lt;&lt;f1.getStr()&lt;&lt;"\tf2 = "&lt;&lt;f2.getStr()&lt;&lt;endl;   return EXIT_SUCCESS; }</code>

     本文轉自Bill_Hoo 51CTO部落格,原文連結:http://blog.51cto.com/billhoo/787040,如需轉載請自行聯系原作者

繼續閱讀