| 導購 | 订阅 | 在线投稿
分享
 
 
當前位置: 王朝網路 >> c/c++ >> C++程序設計最佳實踐
 

C++程序設計最佳實踐

2008-06-01 02:05:04  編輯來源:互聯網  简体版  手機版  評論  字體: ||
 
 
  隨著計算機語言的發展,我們現在編寫一個程序越來越輕易了。利用一些軟件開發工具,往往只要通過鼠標的拖拖點點,計算機就會自動幫你生成許多代碼。但在很多時候,計算機的這種能力被濫用了,我們往往只考慮把這個程序搭起來,而不去考慮程序的性能如何,程序是否足夠的健壯。

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  而此節課的目的主要是介紹一些編碼的經驗,讓大家編寫的程序更加健壯和高性能。1、PRefer const and inline to #define

  在C++編程中應該盡量使用const和inline來代替#define,盡量做到能不用#define就不用。#define常見的用途有「定義常量」以及「定義宏」,但其中存在諸多的弊病。

  第一,查錯不直觀,不利于調試。Define的定義是由預處理程序處理的,作的是完全的文本替換,不做任何的類型檢查。在編譯器處理階段,define定義的東西已經被完全替換了,這樣在debug的時候就看不到任何的相關信息,即跟蹤時不能step into宏。例如,把aspECT_RATIO用define定義成1.653,編譯器就看不到ASPECT_RATIO這個名字了。假如編譯器報1.653錯,那麽就無從知道此1.653來自于何處。在真正編碼的時候應該使用如下的語句來定義:

  static const double ASPECT_RATIO = 1.653;

  第二,沒有任何類型信息,不是type safe。因爲它是文本級別的替換,這樣不利于程序的維護。

  第三,define的使用很輕易造成汙染。比如,假如有兩個頭文件都定義了ASPECT_RATIO, 而一個CPP文件又同時包含了這兩個頭文件,那麽就會造成沖突。更難查的是另外一種錯誤,比如有如下的代碼:

  // in header file def.h

  #define Apple 1

  #define Orange 2

  #define Pineapple 3

  …

  // in some cpp file that includes the def.h

  enum Colors {White, Black, Purple, Orange};

  在.h文件中Orange被定義成水果的一種,而在.cpp文件中Orange又成爲了一種顔色,那麽編譯器就會把此處的Orange替換成2,編譯可能仍然可以通過,程序也能夠運行,但是這就成了一個bug,表現出古怪的錯誤,且很難查錯。再比如定義了一個求a與b哪個數大的宏,#define max(a,b) ((a) > (b) ? (a) : (b))

  int a = 5, b = 0;

  max(++ a, b);

  max(++ a, b + 10);

  在上面的操作中,max(++ a, b); 語句中a被++了兩次,而max(++ a, b + 10); 語句中a只加了一次,這樣在程序處理中就很有可能成爲一個bug,且此bug也非常的難找。在實際編碼時可以使用如下的語句來做:

  template<class T>

  inline const T&

  max(const T& a, const T& b) { return a > b ? a : b; }

  2、Prefer C++-style casts

  在程序中經常會需要把一種類型轉換成另外一種類型,在C++中應該使用static_cast、const_cast、dynamic_cast、reinterpret_cast要害字來做類型轉換。因爲這有以下好處,一是其本身就是一種注釋,在代碼中看到上面這些要害字就可馬上知道此處是進行類型轉換。二是C語言中類型轉換通常是很難進行搜索的,而通過要害字cast則可以很輕易的找到程序中出現類型轉換的地方了。

  3、Distinguish between prefix and postfix forms of increment and decrement Operators

  通常對于操作系統或編譯器自身支持的類型,prefix(前綴,如++i)與postfix(後綴,如i++)的效果是一樣的。因爲現在的編譯器都很聰明,它會自動做優化,這兩者的彙編代碼是一樣的,性能不會有差別。但有時候也會有不同的,如一些重載了操作符的類型。下面是模擬prefix與postfix的操作過程,可以發現在postfix操作中會生成一個臨時變量,而這一臨時變量是會占用額外的時間和開銷的。

  

   // prefix form: increment and fetch

  UPInt& UPInt::operator++()

  {

  *this += 1; // increment

  return *this; // fetch

  }

  // postfix form: fetch and increment

  const UPInt UPInt::operator++(int)

  {

  UPInt oldValue = *this; // fetch

  ++(*this); // increment

  return oldValue; // return what was fetched

  }

  一般情況下不需要區分是先++,還是後++,但是我們在編寫程序的時候最好能習慣性的將其寫成++i的形式,如在使用STL中的iterator時,prefix與postfix會有相當大的性能差異。請不要小看這些細節,實際在編寫程序的時候,若不注重具體細節,你會發現程序的性能會非常的低。但要注重,雖然在大多數情況下可以用prefix來代替postfix,但有一種情況例外,那就是有[]操作符時,比如gzArray [++index] 是不等于 gzArray[index++]的。

  

C++程序設計最佳實踐
更多內容請看C/C++技術專題 C/C++進階技術文檔 C/C++相關文章專題,或

  4、Minimizing Compile-time Dependencies

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  有些人在編寫程序時,往往喜歡將一個.h文件包含到另一個.h文件,而實踐證實在做大型軟件時這是一個非常不好的習慣,因這樣會造成很多依靠的問題,包含較多的.h文件,別人又使用了這個class,而在他的那個工程中可能並不存在這些.h文件,這樣很可能就編譯不能通過。而且這樣做,還可能造成很難去更新一個模塊的情況。因爲一個.h文件被很多模塊包含的話,假如修改了此.h文件,在編譯系統的時候,編譯器會去尋找哪些模塊依靠于某個被修改過的.h文件,那麽就導致了所有包含入此.h文件的模塊全都要進行重新編譯。在項目比較小的時候,大家可能還感覺不到差別,但是假如說是在大型的軟件系統裏,你可能編譯一遍源碼需要七、八個小時。假如你這個.h文件被很多模塊包含的話,就算在.h文件中加了一行注釋,在編譯時編譯器檢查哪些文件被改動,那麽所有包含入此.h文件的模塊都會被重新編譯,造成巨大的時間和精力負擔。對于此問題,解決的方法就是讓.h文件自包含,也就是說讓它包含盡量少的東西。所謂盡量少是指如刪掉任何一個它包含進來的.h文件,都將無法正常進行工作。其實在很多情況下,並不需要一個.h文件去包含另一個.h文件,完全可以通過class聲明來解決依靠關系的這種問題。再來看下面這個例子:

  #include "a.h" // class A

  #include "b.h" // class B

  #include "c.h" // class C

  #include "d.h" // class D

  #include "e.h" // class E

  class X : public A, private B

  {

  public:

  E SomeFunctionCall(E someParameter);

  private:

  D m_dInstance;

  };

  當類X從類A和類B中派生時,需要知道X在內存中都有哪些data,通常在內存中前面是基類的data,後面緊跟的是此派生類自身定義的data,因此就必須知道類A與類B的內部細節,要不然編譯器就無法來安排內存了。但是在處理參數以及參數返回值的時候,實際上並不需要知道這些信息,在此處定義的SomeFunctionCall()只需知道E是個class就足夠了,並不需要知道類E中的data如長度等的具體細節。上面的代碼應該改寫成如下的形式,以減少依靠關系:

  #include "a.h" // class A

  #include "b.h" // class B

  #include "c.h" // class C

  #include "d.h" // class D

  class E;

  class X : public A, private B

  {

  public:

  E SomeFunctionCall(E someParameter);

  private:

  D m_dInstance;

  };

  5、Never treat arrays polymorphically

  不要把數組和多態一起使用,請看下面的例子。

  class BST { ... };

  class BalancedBST: public BST { ... };

  void printBSTArray(ostream& s, const BST array[], int numElements)

  {

  for (int i = 0; i < numElements; ++i)

  {

  s << array[i];

  // this assumes an operator<< is defined for BST

  

   }

  }

  BalancedBST bBSTArray[10];

  printBSTArray(cout, bBSTArray, 10);

  數組在內存中是一個連續的內存空間,而在數組中應該如何來定位一個元素呢?過程是這樣的,編譯器可以知道每個數據類型的長度大小,假如數組的index是0,則會自動去取第一個元素;假如是指定了某個index,編譯器則會根據此index與該數據類型的長度自動去算出該元素的位置。

  在printBSTArray()函數中,盡管傳入的參數是BalancedBST類型,但由于其本來定義的類型是BST,那麽它依然會根據BST來計算類型的長度。而通常派生類實例所占的內存要比基類實例所占的內存大一些,因此該程序在編譯時會報錯。請記住,永遠不要把數組和C++的多態性放在一起使用。

  6、Prevent exceptions from leaving destrUCtors

  析構函數中一定不要抛出異常。通常有兩種情況會導致析構函數的調用,一種是當該類的對象離開了它的域,或delete表達式中一個該類對象的指針,另一種是由于異常而引起析構函數的調用。

  假如析構函數被調用是由于exception引起,而此時在析構函數中又抛出了異常,程序會立即被系統終止,甚至都來不及進行內存釋放。因此假如在析構函數中抛出異常的話,就很輕易混淆引起異常的原因,且這樣的軟件也會讓用戶非常惱火。由于析構函數中很可能會調用其它的一些函數,所以在寫析構函數的時候一定要注重,對這些函數是否會抛出異常要非常清楚,假如會的話,就一定要小心了。比如下面這段代碼:

  session::~Session()

  {

  logDestruction(this);

  }

  比如logDestruction()函數可能會抛出異常,那麽我們就應該采用下面這種代碼的形式:

  Session::~Session()

  {

  try

  {

  logDestruction(this);

  }

  catch (...)

  {

  }

  }

  這樣程序出錯的時候不會被立即關掉,可以給用戶一些其它的選擇,至少先讓他把目前在做的工作保存下來。

  7、Optimization:Remember the 80-20 rule

  在軟件界有一個20-80法則,其實這是一個很有趣的現象,比如一個程序中20%的代碼使用了該程序所占資源的80%;一個程序中20%的代碼占用了總運行時間的80%;一個程序中20%的代碼使用了該程序所占內存的80%;在20%的代碼上面需要花費80%的維護力量,等等。這個規律還可以被繼續推廣下去,不過這個規律無法被證實,它是人們在實踐中觀察得出的結果。從這個規律出發,我們在做程序優化的時候,就有了針對性。比如想提高代碼的運行速度,根據這個規律可以知道其中20%的代碼占用了80%的運行時間,因此我們只要找到這20%的代碼,並進行相應的優化,那麽我們程序的運行速度就可以有較大的提高。再如有一個函數,占用了程序80%的運行時間,假如把這個函數的執行速度提高10倍,那麽對程序整體性能的提高,影響是非常巨大的。假如有一個函數運行時間只占總時間的1%,那就算把這個函數的運行速度提高1000倍,對程序整體性能的提高也是影響不大的。所以我們的基本思想就是找到占用運行時間最大的那個函數,然後去優化它,哪怕只是改進了一點點,程序的整體性能也可以被提高很多。

  要想找出那20%的代碼,我們的方法就是使用Profiler,它實際上是一些公司所開發的工具,可以檢查程序中各個模塊所分配內存的使用情況,以及每個函數所運行的時間等。常見的Profiler有Intel公司開發的VTune,微軟公司開發的Visual Studio profiler,DevPartner from Compuware等。

C++程序設計最佳實踐
更多內容請看C/C++技術專題 C/C++進階技術文檔 C/C++相關文章專題,或
 
 
 
上一篇《C++:誰動了我的指針》
下一篇《C++Builder動態更改自定義打印紙張》
 
 
 
 
 
 
日版寵物情人插曲《Winding Road》歌詞

日版寵物情人2017的插曲,很帶節奏感,日語的,女生唱的。 最後聽見是在第8集的時候女主手割傷了,然後男主用嘴幫她吸了一下,插曲就出來了。 歌手:Def...

兄弟共妻,我成了他們夜裏的美食

老鍾家的兩個兒子很特別,就是跟其他的人不太一樣,魔一般的執著。兄弟倆都到了要結婚的年齡了,不管自家老爹怎麽磨破嘴皮子,兄弟倆說不娶就不娶,老父母爲兄弟兩操碎了心...

如何磨出破洞牛仔褲?牛仔褲怎麽剪破洞?

把牛仔褲磨出有線的破洞 1、具體工具就是磨腳石,下面墊一個硬物,然後用磨腳石一直磨一直磨,到把那塊磨薄了,用手撕開就好了。出來的洞啊很自然的。需要貓須的話調幾...

我就是掃描下圖得到了敬業福和愛國福

先來看下敬業福和愛國福 今年春節,支付寶再次推出了“五福紅包”活動,表示要“把欠大家的敬業福都還給大家”。 今天該活動正式啓動,和去年一樣,需要收集“五福”...

冰箱異味産生的原因和臭味去除的方法

有時候我們打開冰箱就會聞到一股異味,冰箱裏的這種異味是因爲一些物質發出的氣味的混合體,聞起來讓人惡心。 産生這些異味的主要原因有以下幾點。 1、很多人有這種習...

《極品家丁》1-31集大結局分集劇情介紹

簡介 《極品家丁》講述了現代白領林晚榮無意回到古代金陵,並追隨蕭二小姐化名“林三”進入蕭府,不料卻陰差陽錯上演了一出低級家丁拼搏上位的“林三升職記”。...

李溪芮《極品家丁》片尾曲《你就是我最愛的寶寶》歌詞

你就是我最愛的寶寶 - 李溪芮 (電視劇《極品家丁》片尾曲) 作詞:常馨內 作曲:常馨內 你的眉 又鬼馬的挑 你的嘴 又壞壞的笑 上一秒吵鬧 下...

烏梅的功效與作用以及烏梅的食用禁忌有哪些?

烏梅,又稱春梅,中醫認爲,烏梅味酸,性溫,無毒,具有安心、除熱、下氣、祛痰、止渴調中、殺蟲的功效,治肢體痛、肺痨病。烏梅泡水喝能治傷寒煩熱、止吐瀉,與幹姜一起制...

什麽是脂肪粒?如何消除臉部脂肪粒?

什麽是脂肪粒 在我們的臉上總會長一個個像脂肪的小顆粒,弄也弄不掉,而且顔色還是白白的。它既不是粉刺也不是其他的任何痘痘,它就是脂肪粒。 脂肪粒雖然也是由油脂...

網絡安全治理:國家安全保障的主要方向是打擊犯罪,而不是處置和懲罰受害者

來源:中國青年報 新的攻擊方法不斷湧現,黑客幾乎永遠占據網絡攻擊的上風,我們不可能通過技術手段杜絕網絡攻擊。國家安全保障的主要方向是打擊犯罪,而不是處置和懲罰...

河南夫妻在溫嶺網絡直播“造人”內容涉黃被刑事拘留

夫妻網絡直播“造人”爆紅   1月9日,溫嶺城北派出所接到南京警方的協查通告,他們近期打掉了一個涉黃直播APP平台。而根據掌握的線索,其中有一對涉案的夫妻主播...

如何防止牆紙老化?牆紙變舊變黃怎麽辦?

如何防止牆紙老化? (1)選擇透氣性好的牆紙 市場上牆紙的材質分無紡布的、木纖維的、PVC的、玻璃纖維基材的、布面的等,相對而言,PVC材質的牆紙最不透氣...

鮮肌之謎非日本生産VS鮮肌之謎假日貨是謠言

觀點一:破日本銷售量的“鮮肌之謎” 非日本生産 近一段時間,淘寶上架了一款名爲“鮮肌之謎的” 鲑魚卵巢美容液,號稱是最近日本的一款推出的全新護膚品,産品本身所...

中國最美古詩詞精選摘抄

系腰裙(北宋詞人 張先) 惜霜蟾照夜雲天,朦胧影、畫勾闌。人情縱似長情月,算一年年。又能得、幾番圓。 欲寄西江題葉字,流不到、五亭前。東池始有荷新綠,尚小如...

關于女人的經典語句

關于女人的經典語句1、【做一個獨立的女人】 思想獨立:有主見、有自己的人生觀、價值觀。有上進心,永遠不放棄自己的理想,做一份自己喜愛的事業,擁有快樂和成就...

未來我們可以和性愛機器人結婚嗎?

你想體驗機器人性愛嗎?你想和性愛機器人結婚嗎?如果你想,機器人有拒絕你的權利嗎? 近日,第二屆“國際人類-機器人性愛研討會”大會在倫敦金史密斯大學落下帷幕。而...

全球最變態的十個地方

10.土耳其地下洞穴城市 變態指數:★★☆☆☆ 這是土耳其卡帕多西亞的一個著名景點,傳說是當年基督教徒們爲了躲避戰爭而在此修建。裏面曾住著20000人,...

科學家稱,人類死亡後意識將在另外一個宇宙中繼續存活

據英國《每日快報》報道,一位科學家兼理論家Robert Lanza博士宣稱,世界上並不存在人類死亡,死亡的只是身體。他認爲我們的意識借助我們體內的能量生存,而且...

《屏裏狐》片頭曲《我愛狐狸精》歌詞是什麽?

《我愛狐狸精》 - 劉馨棋   (電視劇《屏裏狐》主題曲)   作詞:金十三&李旦   作曲:劉嘉   狐狸精 狐狸仙   千年修...

 
 
 
  隨著計算機語言的發展,我們現在編寫一個程序越來越輕易了。利用一些軟件開發工具,往往只要通過鼠標的拖拖點點,計算機就會自動幫你生成許多代碼。但在很多時候,計算機的這種能力被濫用了,我們往往只考慮把這個程序搭起來,而不去考慮程序的性能如何,程序是否足夠的健壯。 而此節課的目的主要是介紹一些編碼的經驗,讓大家編寫的程序更加健壯和高性能。  1、PRefer const and inline to #define   在C++編程中應該盡量使用const和inline來代替#define,盡量做到能不用#define就不用。#define常見的用途有「定義常量」以及「定義宏」,但其中存在諸多的弊病。   第一,查錯不直觀,不利于調試。Define的定義是由預處理程序處理的,作的是完全的文本替換,不做任何的類型檢查。在編譯器處理階段,define定義的東西已經被完全替換了,這樣在debug的時候就看不到任何的相關信息,即跟蹤時不能step into宏。例如,把aspECT_RATIO用define定義成1.653,編譯器就看不到ASPECT_RATIO這個名字了。假如編譯器報1.653錯,那麽就無從知道此1.653來自于何處。在真正編碼的時候應該使用如下的語句來定義: static const double ASPECT_RATIO = 1.653;   第二,沒有任何類型信息,不是type safe。因爲它是文本級別的替換,這樣不利于程序的維護。   第三,define的使用很輕易造成汙染。比如,假如有兩個頭文件都定義了ASPECT_RATIO, 而一個CPP文件又同時包含了這兩個頭文件,那麽就會造成沖突。更難查的是另外一種錯誤,比如有如下的代碼:   // in header file def.h   #define Apple 1   #define Orange 2     #define Pineapple 3    …   // in some cpp file that includes the def.h   enum Colors {White, Black, Purple, Orange};   在.h文件中Orange被定義成水果的一種,而在.cpp文件中Orange又成爲了一種顔色,那麽編譯器就會把此處的Orange替換成2,編譯可能仍然可以通過,程序也能夠運行,但是這就成了一個bug,表現出古怪的錯誤,且很難查錯。再比如定義了一個求a與b哪個數大的宏,#define max(a,b) ((a) > (b) ? (a) : (b))   int a = 5, b = 0;   max(++ a, b);   max(++ a, b + 10);   在上面的操作中,max(++ a, b); 語句中a被++了兩次,而max(++ a, b + 10); 語句中a只加了一次,這樣在程序處理中就很有可能成爲一個bug,且此bug也非常的難找。在實際編碼時可以使用如下的語句來做:   template<class T>   inline const T&   max(const T& a, const T& b) { return a > b ? a : b; }   2、Prefer C++-style casts   在程序中經常會需要把一種類型轉換成另外一種類型,在C++中應該使用static_cast、const_cast、dynamic_cast、reinterpret_cast要害字來做類型轉換。因爲這有以下好處,一是其本身就是一種注釋,在代碼中看到上面這些要害字就可馬上知道此處是進行類型轉換。二是C語言中類型轉換通常是很難進行搜索的,而通過要害字cast則可以很輕易的找到程序中出現類型轉換的地方了。   3、Distinguish between prefix and postfix forms of increment and decrement Operators   通常對于操作系統或編譯器自身支持的類型,prefix(前綴,如++i)與postfix(後綴,如i++)的效果是一樣的。因爲現在的編譯器都很聰明,它會自動做優化,這兩者的彙編代碼是一樣的,性能不會有差別。但有時候也會有不同的,如一些重載了操作符的類型。下面是模擬prefix與postfix的操作過程,可以發現在postfix操作中會生成一個臨時變量,而這一臨時變量是會占用額外的時間和開銷的。   // prefix form: increment and fetch   UPInt& UPInt::operator++()    {     *this += 1; // increment    return *this; // fetch    }   // postfix form: fetch and increment    const UPInt UPInt::operator++(int)    {     UPInt oldValue = *this; // fetch    ++(*this); // increment     return oldValue; // return what was fetched    }   一般情況下不需要區分是先++,還是後++,但是我們在編寫程序的時候最好能習慣性的將其寫成++i的形式,如在使用STL中的iterator時,prefix與postfix會有相當大的性能差異。請不要小看這些細節,實際在編寫程序的時候,若不注重具體細節,你會發現程序的性能會非常的低。但要注重,雖然在大多數情況下可以用prefix來代替postfix,但有一種情況例外,那就是有[]操作符時,比如gzArray [++index] 是不等于 gzArray[index++]的。 [url=/bbs/detail_1785335.html][img]http://image.wangchao.net.cn/it/1323423846557.gif[/img][/url] 更多內容請看C/C++技術專題 C/C++進階技術文檔 C/C++相關文章專題,或   4、Minimizing Compile-time Dependencies   有些人在編寫程序時,往往喜歡將一個.h文件包含到另一個.h文件,而實踐證實在做大型軟件時這是一個非常不好的習慣,因這樣會造成很多依靠的問題,包含較多的.h文件,別人又使用了這個class,而在他的那個工程中可能並不存在這些.h文件,這樣很可能就編譯不能通過。而且這樣做,還可能造成很難去更新一個模塊的情況。因爲一個.h文件被很多模塊包含的話,假如修改了此.h文件,在編譯系統的時候,編譯器會去尋找哪些模塊依靠于某個被修改過的.h文件,那麽就導致了所有包含入此.h文件的模塊全都要進行重新編譯。在項目比較小的時候,大家可能還感覺不到差別,但是假如說是在大型的軟件系統裏,你可能編譯一遍源碼需要七、八個小時。假如你這個.h文件被很多模塊包含的話,就算在.h文件中加了一行注釋,在編譯時編譯器檢查哪些文件被改動,那麽所有包含入此.h文件的模塊都會被重新編譯,造成巨大的時間和精力負擔。對于此問題,解決的方法就是讓.h文件自包含,也就是說讓它包含盡量少的東西。所謂盡量少是指如刪掉任何一個它包含進來的.h文件,都將無法正常進行工作。其實在很多情況下,並不需要一個.h文件去包含另一個.h文件,完全可以通過class聲明來解決依靠關系的這種問題。再來看下面這個例子:   #include "a.h" // class A   #include "b.h" // class B   #include "c.h" // class C   #include "d.h" // class D   #include "e.h" // class E   class X : public A, private B   {    public:   E SomeFunctionCall(E someParameter);    private:    D m_dInstance;   };   當類X從類A和類B中派生時,需要知道X在內存中都有哪些data,通常在內存中前面是基類的data,後面緊跟的是此派生類自身定義的data,因此就必須知道類A與類B的內部細節,要不然編譯器就無法來安排內存了。但是在處理參數以及參數返回值的時候,實際上並不需要知道這些信息,在此處定義的SomeFunctionCall()只需知道E是個class就足夠了,並不需要知道類E中的data如長度等的具體細節。上面的代碼應該改寫成如下的形式,以減少依靠關系:   #include "a.h" // class A   #include "b.h" // class B   #include "c.h" // class C   #include "d.h" // class D   class E;   class X : public A, private B   {    public:   E SomeFunctionCall(E someParameter);    private:   D m_dInstance;   };   5、Never treat arrays polymorphically   不要把數組和多態一起使用,請看下面的例子。   class BST { ... };   class BalancedBST: public BST { ... };   void printBSTArray(ostream& s, const BST array[], int numElements)   {   for (int i = 0; i < numElements; ++i)   {    s << array[i];   // this assumes an operator<< is defined for BST   }   }   BalancedBST bBSTArray[10];   printBSTArray(cout, bBSTArray, 10);   數組在內存中是一個連續的內存空間,而在數組中應該如何來定位一個元素呢?過程是這樣的,編譯器可以知道每個數據類型的長度大小,假如數組的index是0,則會自動去取第一個元素;假如是指定了某個index,編譯器則會根據此index與該數據類型的長度自動去算出該元素的位置。   在printBSTArray()函數中,盡管傳入的參數是BalancedBST類型,但由于其本來定義的類型是BST,那麽它依然會根據BST來計算類型的長度。而通常派生類實例所占的內存要比基類實例所占的內存大一些,因此該程序在編譯時會報錯。請記住,永遠不要把數組和C++的多態性放在一起使用。   6、Prevent exceptions from leaving destrUCtors   析構函數中一定不要抛出異常。通常有兩種情況會導致析構函數的調用,一種是當該類的對象離開了它的域,或delete表達式中一個該類對象的指針,另一種是由于異常而引起析構函數的調用。   假如析構函數被調用是由于exception引起,而此時在析構函數中又抛出了異常,程序會立即被系統終止,甚至都來不及進行內存釋放。因此假如在析構函數中抛出異常的話,就很輕易混淆引起異常的原因,且這樣的軟件也會讓用戶非常惱火。由于析構函數中很可能會調用其它的一些函數,所以在寫析構函數的時候一定要注重,對這些函數是否會抛出異常要非常清楚,假如會的話,就一定要小心了。比如下面這段代碼:   session::~Session()   {   logDestruction(this);   }   比如logDestruction()函數可能會抛出異常,那麽我們就應該采用下面這種代碼的形式:   Session::~Session()   {    try   {    logDestruction(this);    }    catch (...)   {    }  }   這樣程序出錯的時候不會被立即關掉,可以給用戶一些其它的選擇,至少先讓他把目前在做的工作保存下來。   7、Optimization:Remember the 80-20 rule   在軟件界有一個20-80法則,其實這是一個很有趣的現象,比如一個程序中20%的代碼使用了該程序所占資源的80%;一個程序中20%的代碼占用了總運行時間的80%;一個程序中20%的代碼使用了該程序所占內存的80%;在20%的代碼上面需要花費80%的維護力量,等等。這個規律還可以被繼續推廣下去,不過這個規律無法被證實,它是人們在實踐中觀察得出的結果。從這個規律出發,我們在做程序優化的時候,就有了針對性。比如想提高代碼的運行速度,根據這個規律可以知道其中20%的代碼占用了80%的運行時間,因此我們只要找到這20%的代碼,並進行相應的優化,那麽我們程序的運行速度就可以有較大的提高。再如有一個函數,占用了程序80%的運行時間,假如把這個函數的執行速度提高10倍,那麽對程序整體性能的提高,影響是非常巨大的。假如有一個函數運行時間只占總時間的1%,那就算把這個函數的運行速度提高1000倍,對程序整體性能的提高也是影響不大的。所以我們的基本思想就是找到占用運行時間最大的那個函數,然後去優化它,哪怕只是改進了一點點,程序的整體性能也可以被提高很多。   要想找出那20%的代碼,我們的方法就是使用Profiler,它實際上是一些公司所開發的工具,可以檢查程序中各個模塊所分配內存的使用情況,以及每個函數所運行的時間等。常見的Profiler有Intel公司開發的VTune,微軟公司開發的Visual Studio profiler,DevPartner from Compuware等。 [url=/bbs/detail_1785335.html][img]http://image.wangchao.net.cn/it/1323423846605.gif[/img][/url] 更多內容請看C/C++技術專題 C/C++進階技術文檔 C/C++相關文章專題,或
󰈣󰈤
 
 
 
  免責聲明:本文僅代表作者個人觀點,與王朝網路無關。王朝網路登載此文出於傳遞更多信息之目的,並不意味著贊同其觀點或證實其描述,其原創性以及文中陳述文字和內容未經本站證實,對本文以及其中全部或者部分內容、文字的真實性、完整性、及時性本站不作任何保證或承諾,請讀者僅作參考,並請自行核實相關內容。
 
 
高清美女攝影(8)
高清美女攝影(7)
高清美女攝影(6)
高清美女攝影(5)
痞子的甘南日記
疑是銀河落九天
雪域壩上四——純美色
冬日戀歌——西城楊柳弄輕柔
 
>>返回首頁<<
 
 熱帖排行
 
 
 
 
© 2005- 王朝網路 版權所有