作者yoco315 (眠月)
看板C_and_CPP
標題Re: [問題] this 在什麼情況下會等於NULL??
時間Fri Apr 2 20:50:34 2010
※ 引述《elefant ()》之銘言:
: : 會這樣設計的原因,
: : 可以參考一個叫做 "Null Pointer(Object) Pattern" 的手法。
「原因」啦 T_T
用來解決同一個問題,但是手法不一樣。
: 就[Refactoring]這本書裡提及的Null Object Pattern
: 感覺和你提到的目的相反耶
: Null Object就是不想"一直檢查是否為null"
: 才會創造一個虛無的object出來
: 還是說我有哪個地方誤會了?
應該沒誤會 O_O
Null Object 的確是為了不想一直檢查 null,
不過我自己是覺得應該是要用在下面這種地方,
舉個例子,假設我寫了一個線上模擬城市的遊戲,
每個玩家的城市都有上下左右四個鄰居,如果我要計算鄰居人口的總和,
┌────────────────────────────────────┐
|size_t all_neighbor_population() { │
| size_t sum = 0 ; │
| if (_left != NULL) sum + _left ->population() ; │
| if (_right != NULL) sum + _right->population() ; │
| if (_up != NULL) sum + _up ->population() ; │
| if (_down != NULL) sum + _down ->population() ; │
| return 0 ; │
|} │
└────────────────────────────────────┘
如果用了 Null Object 的話,就可以這樣寫
┌────────────────────────────────────┐
|size_t all_neighbor_population() { │
| return _left ->population() + │
| _right->population() + │
| _up ->population() + │
| _down ->population() ; │
|} │
└────────────────────────────────────┘
Null Object Pattern 使用的原因在於:
「對於 null 的 object,其 member function 有適合的預設值」
像這樣的狀況,我們就可以不用先檢查 if ( obj != NULL ),
而可以直接呼叫 obj->func() 來取得結果。
要實現這件事,有兩個方法:
a. 可以像 design pattern 裡面講的,用繼承的方式作到,
b. 也可以在 member function 裡面檢查 this 來作到。
那什麼狀況下我們會需要用到第一種方法?
有沒有發現很奇怪,明明第二種方法有明顯的好處:
1. 實作更簡單:直接 if 就好了,省去撰寫整個 NullClass。
2. 效能更好:因為免去了 virtual function 的呼叫成本,還可以 inline!
那為什麼會有需要第一種狀況?為什麼書上會寫第一種方法?
因為 Java 會在呼叫的當下檢查 Null,所以 Java 只能用 a。 XD
很多人看到 if (this) 都覺得很奇怪這樣不會 core dump 嗎?
C++ 的確不會 core dump,但是 Java 會 NullPointerException,哈哈哈,
這邊在 C++ 只是單純的跳到那個 member function 的位置去繼續執行,
一直到程式碼去存取 data member 的時候才會發生 invalid access。
但是 Java 會在 member function 呼叫的當下進行指標的檢查
(揪甘心ㄟ),
(新一版 Java 終於有語法可以避開 NullPointerException 啦~!)
所以如果 this 是 null,Java 當下就給你一個 exception,黯然回首。
一個觀點是 Design Pattern 的存在是因為語言本身的不足。
正因為語言沒有提供這個功能,所以我們透過 Design Pattern 去作到某些事,
比方說沒有 multi-method 的語言會要用到 visitor 去模擬,
或是沒有 multiple inhertance 的語言會去用 adaptor/decorator 模擬。
話說 Design Pattern 發展最蓬勃的時候剛好也是 Java 最流行的時候 XD
真巧。(我沒有說 Java 很不足,這是別人說的 XD)
--
To iterate is human, to recurse, divine.
遞迴只應天上有, 凡人該當用迴圈. L. Peter Deutsch
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 118.160.115.202
推 PsMonkey:C++ 只應天上有,凡人該當用 Java -- PsMonkey [核爆] 04/02 21:25
→ remmurds:其實這篇也某種程度反映出C++仍有很多不足的地方 04/02 21:29
→ yoco315:沒錯, 所謂的 Effective C++ 其實是 Defective C++ XD 04/02 21:46
推 Bencrie:這個 syntax highlight theme是 ... Turbo C++ v3 XD? 04/02 22:08
推 VictorTom:還是C語言比較和藹可親一點....XD 04/02 22:10
→ sbrhsieh:提到的 C++ case 是 non-virtual function call, 嚴格說 04/02 22:21
→ sbrhsieh:跟 Java case 的意義不完全一樣。 04/02 22:21
→ yoco315:對阿 tc3 04/02 22:27
推 littleshan:雖然對java有酸到 但我還是笑了 XD 04/02 23:11
→ yoco315:這真的不是我說的 XD 是前幾天在別的地方看到的 XD 04/02 23:49
推 legendmtg:前幾天我好像也有看到XD 04/03 00:04
推 holymars: 推薦這篇文章 04/03 00:05
推 zha0:推顏色 04/03 00:26
推 tomap41017:哈哈哈是C老師的梗嗎?XD 04/03 02:52
推 bobhsiao:第一個藍色方塊,裡面應該是 sum "+=" 吧? 04/04 00:47