[問題] 物件指標為NULL,其成員指標變數的存取

看板C_and_CPP (C/C++)作者 (十三)時間15年前 (2010/10/29 11:45), 編輯推噓4(4015)
留言19則, 2人參與, 最新討論串1/2 (看更多)
( *[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

10/29 11:56, , 1F
你可以這樣做, 詳細的名稱我忘記了, 但是這樣寫就會
10/29 11:56, 1F

10/29 11:57, , 2F
變成有幾個成員函式就要重複幾次判斷的程式碼, 雖然我
10/29 11:57, 2F

10/29 11:58, , 3F
會建議你用 smart_ptr, 但是它們的 get、operator*、
10/29 11:58, 3F

10/29 11:58, , 4F
operator-> 都是不丟例外的作法, 所以你可能需要繼承
10/29 11:58, 4F

10/29 12:01, , 5F
下來, 再自己覆寫 operator-> 作判斷, 要勤勞點也可以
10/29 12:01, 5F

10/29 12:01, , 6F
每次存取前都用get來檢查啦
10/29 12:01, 6F

10/29 12:07, , 7F
以上是對 class_a 沒有指向物件就呼叫成員函式的解決
10/29 12:07, 7F

10/29 12:08, , 8F
方案, 接著針對testp來講, testp指到的記憶體既然會在
10/29 12:08, 8F

10/29 12:10, , 9F
dtor裡被清除, 表示他跟類別的關係是 Composition, 那
10/29 12:10, 9F

10/29 12:11, , 10F
我會建議ctor內就把它配置好會比較適當, 這樣比較符合
10/29 12:11, 10F

10/29 12:11, , 11F
RAII的概念, 不然你再多寫一個類別把這些要配置的成員
10/29 12:11, 11F

10/29 12:13, , 12F
包在一起, 在 CLASSA 這邊也會比較好管理
10/29 12:13, 12F

10/29 14:09, , 13F
應該是null object pattern
10/29 14:09, 13F

10/29 14:09, , 14F
另外delete前可以不用測試指標(只要非NULL就刪掉)
10/29 14:09, 14F

10/29 14:41, , 15F
之前出現的名詞好像是 null pointer pattern, 如果也
10/29 14:41, 15F

10/29 14:42, , 16F
叫 null object pattern 我會沒辦法接受, 因為那就變
10/29 14:42, 16F

10/29 14:43, , 17F
成「check is nothing or not」而不是「do nothing」
10/29 14:43, 17F

10/29 14:43, , 18F
責任的分配也比較怪
10/29 14:43, 18F

10/29 19:28, , 19F
抱歉!記錯了!我也覺得怪怪的XD
10/29 19:28, 19F
文章代碼(AID): #1CoaDEuT (C_and_CPP)
文章代碼(AID): #1CoaDEuT (C_and_CPP)