※ 引述《godfat (godfat 真常)》之銘言:
: 最直覺的做法當然是 operator[](size_t, size_t), 問題是這在 C++ 下
: 是做不到的。實作 proxy 再用 [][] 去 call 感覺很順,但做起來之麻煩…
在實務上我碰過,實做 proxy 再用 [][] 去 call 的方法,反而(也許)
比較恰當的情況:
在已經有成堆的使用 C 2D array 的 code 時,為了要 check boundary
以便捉錯,並 raise exception 以避免把程式直接整個當掉。此時,模
擬原本 C 的語法,實做 proxy 再用 [][] 去 call,就可以取代原本的
C 2D array,而在 operator [] 裡 check boundary,若失敗則 raise
exception。既有的程式都不必修改,僅需重新編譯即可。
不過,這招還是有個缺點就是,因為與原本的 C 語法完全相同,因此也
沒有辦法「確認」所有用到的地方,都已經換用 C++ 版本了。這個問題
「部份」可以這麼解:
假設原來使用的型別是 int[][] 經 typedef 成 int2d_t,新版 class
叫做 Array2D<int> 一樣被 typedef 成 int2d_t。我們可以援引 boost
的 static asssertion 與 type traits 技術,暫時地用 script 將下
面程式加到所有 .cpp 檔後面,然後編譯程式即可揪出有問題的 .cpp
檔。
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
BOOST_STATIC_ASSERT(is_same<Array2D<int>, int2d_t>::value);
但即使如此,我們還是無法避免以後的 programmer,使用到舊的、錯誤
的 C 版本的 int2d_t (老 C programmer 常會直接用 int** 或 int[][]
接 int2d_t 參數,因為這在 C 裡面是一樣的東西)。
所以我個人還是傾向於,實做 Array2D::get(size_t x, size_t y) 來取
代舊的 int[][],然後短痛一次把所有將變數當成 int[][] 在用的程式,
全部換成用 .get(x, y) 來存取。
--
我的微笑,堅持要有鼻子。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 211.21.73.227
※ 編輯: JeffHung 來自: 211.21.73.227 (01/04 19:51)