看板 C_and_CPP 關於我們 聯絡資訊
( *[1m *[m 為色碼,可以按 Ctrl+V 預覽會顯示的顏色 ) ( 未必需要依照此格式,文章條理清楚即可 ) 遇到的問題: (題意請描述清楚) 當物件指標為NULL,存取其成員的指標變數,造成Access violation。 希望得到的正確結果: 避免Access violation。 程式跑出來的錯誤結果: Access violation。 開發平台: (例: VC++ or gcc/g++ or Dev-C++, Windows or Linux) VC++, VS 2008 有問題的code: (請善用置底文標色功能) 舉例: class CLASSA { public: CLASSA() { testp = NULL; // 以下假設呼叫一個函數來new testp,略 } ~CLASSA() { if(testp != NULL) { delete testp; testp = NULL; } } int doSomething(); int *testp; }; int CLASSA::doSomething() { // 這裡開始存取testp return 0; } CLASSA *class_a = NULL; int main() { // class_a尚未new,但是故意呼叫 class_a->doSomething(); // 以後是正常的code,會new class_a和做一些操作,最後delete class_a return 0; } 補充說明: 在故意呼叫的情況下,class_a還沒有new過, testp連NULL都不是,程式執行到doSomething()時,發生Access violation。 我有想過改成 int CLASSA::doSomething() { if(this != NULL) { //原本存取testp的code } else { return 1; } return 0; } 因為不希望隨便一個人加一段code程序就被毀掉, 可是不確定這是標準的寫法,想請教一般標準的寫法如何? 謝謝。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.25.240.120
loveme00835:你可以這樣做, 詳細的名稱我忘記了, 但是這樣寫就會 10/29 11:56
loveme00835:變成有幾個成員函式就要重複幾次判斷的程式碼, 雖然我 10/29 11:57
loveme00835:會建議你用 smart_ptr, 但是它們的 get、operator*、 10/29 11:58
loveme00835:operator-> 都是不丟例外的作法, 所以你可能需要繼承 10/29 11:58
loveme00835:下來, 再自己覆寫 operator-> 作判斷, 要勤勞點也可以 10/29 12:01
loveme00835:每次存取前都用get來檢查啦 10/29 12:01
loveme00835:以上是對 class_a 沒有指向物件就呼叫成員函式的解決 10/29 12:07
loveme00835:方案, 接著針對testp來講, testp指到的記憶體既然會在 10/29 12:08
loveme00835:dtor裡被清除, 表示他跟類別的關係是 Composition, 那 10/29 12:10
loveme00835:我會建議ctor內就把它配置好會比較適當, 這樣比較符合 10/29 12:11
loveme00835:RAII的概念, 不然你再多寫一個類別把這些要配置的成員 10/29 12:11
loveme00835:包在一起, 在 CLASSA 這邊也會比較好管理 10/29 12:13
tomap41017:應該是null object pattern 10/29 14:09
tomap41017:另外delete前可以不用測試指標(只要非NULL就刪掉) 10/29 14:09
loveme00835:之前出現的名詞好像是 null pointer pattern, 如果也 10/29 14:41
loveme00835:叫 null object pattern 我會沒辦法接受, 因為那就變 10/29 14:42
loveme00835:成「check is nothing or not」而不是「do nothing」 10/29 14:43
loveme00835:責任的分配也比較怪 10/29 14:43
tomap41017:抱歉!記錯了!我也覺得怪怪的XD 10/29 19:28