国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

使用C++異常來取代exit()函數

2019-11-17 05:49:03
字體:
來源:轉載
供稿:網友

  從C語言開始接觸C++的人,恐怕都知道exit()這個函數,似乎現在很多的程序員都有這樣一種習慣,在程序一碰到錯誤、或任務剛完成時,把調用exit()函數當成是一種最好的結束程序的方法。
在以前遺留的許多老式C/C++代碼中,這種現象非常普遍,但當手頭的軟件項目逐步進展并越來越大時,就不得不面臨合并以前分散的各個模塊這項工作,此時,假如還有人記得起軟件日志記錄、錯誤寬容度、或至少適當的清理工作,就已經是萬幸了。本文中要說的方法,決不是一條設計準則,但是可減輕修正那些未良好設計及實現的老式代碼時所帶來的痛苦。

  用return來取代exit,無疑是解決此問題最顯而易見的方法,假如軟件項目非常簡單,這也是最高效的解決方案;然而,項目中經常有成打的函數分布在多個源文件中,且這些函數的調用也嵌套在很深的層次中,那么,事情就變得棘手了。假如在這種情況中,所有的函數都返回void,還是有可能修改它們,讓其返回一個退出碼(exit code)的,但所付出的代價也很大;假如函數已經能返回一個有意義的值,只是在碰到錯誤時,調用了exit(),那么這項工作會變得更消耗時間,也會更加輕易出錯。這里說點題外話,使用exit()也是有可取之處的,當老式代碼沒有設計返回任何東西時,假如想得到返回碼(return code),只有靠exit()了。

  有關此問題,還是有一個解決方法的,在這種情況下,我們假定所有的源代碼已經為C++格式,或無需全部編譯就可以移植為C++格式,把所有exit出現的地方全部換成throw(這可以自動完成,甚至無須理解老代碼是怎樣工作的);接著,在任何適當的地方,捕捉為整數的異常碼,這種方法還可依據嚴重性或恢復程度的不同,在不同層面上處理錯誤。

  請看以下示例,原始代碼如下:

// main.cpp
void main() {
 //初始化
 ...
 PRocessMail(...);
}

//另一個源文件
void ProcessMail(...) {
 //初始化
 ...
 if ( initializationError ) {
  printf("faild to init!!!/n");
  exit(-1);
 }
 while ( !shutdown ) {
  ReadMail(...)
  //繼續處理
  ...
 }
}

void ReadMail(...)
{
 ...
 //對ReadBytes()的調用出現在函數內的多處地方,包括在循環中。
 nBytesAvailable = ReadBytes(...)
 ...
}

//另一個源文件
int ReadBytes(...)
{
 //讀取數據
 ...
 if ( error ) {
  printf("there was an error!!/n");
  exit(-1);
 }
 return nBytesRead;
}進入討論組討論。

  在原始代碼中缺少恢復或日志記錄的功能,假如發生了一個錯誤,程序就會"消失"不見了,讓用戶手足無措。下面是重新組織后的代碼,注重,沒有修改函數修飾符:

void main() {
 //初始化
 ...
 try {
  ProcessMail(...);
 } catch (int ret) {
  switch (ret) {
   case E_INITIALIZATION_FAILURE: ...
   case E_IRRECOVERABLE: ...
   ...
  }
 }
}

void ProcessMail(...) {
 //初始化
 ...
 if ( initializationError ) {
  throw(E_INITIALIZATION_FAILURE);
 }

 while ( !shutdown ) {
  try {
   ReadMail(...)
  } catch (int ret) {
   switch (ret) {
    case E_READ_ERROR:
     //記錄錯誤信息
     ...
     //試圖恢復
     ...
     if ( recovered ) {
      continue;
     } else {
      throw(E_IRRECOVERABLE);
     }
     break;
    case ...
   }
  }
  //繼續處理
  ...
 }

 //throw()可以用來取代缺少的返回碼
 //但也要注重由此帶來的性能損失

 throw(S_OK);
} // ProcessMail()

void ReadMail(...)
{
 ...
 //在此無須捕捉異常
 nBytesAvailable = ReadBytes(...)
 ...
}

int ReadBytes(...)
{
 //讀取數據
 if ( error ) {
  throw(E_READ_ERROR);
 }
 return nBytesRead;
}
  現在,修改以前遺留的老式項目時,是不是多點信心了呢?進入討論組討論。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 乌拉特后旗| 江孜县| 鄂伦春自治旗| 大洼县| 隆尧县| 五家渠市| 绥德县| 乐清市| 永胜县| 嘉义县| 大丰市| 南康市| 从化市| 凤台县| 平湖市| 兴安县| 长泰县| 泉州市| 镇巴县| 平原县| 威远县| 牡丹江市| 色达县| 南涧| 白山市| 永川市| 玛多县| 吴桥县| 天镇县| 宝清县| 昌邑市| 桦川县| 农安县| 安庆市| 丹巴县| 济南市| 讷河市| 通许县| 金堂县| 原平市| 龙泉市|