Re: [語法] STL sort 在一個 Class 裡面含很多priv …

看板C_and_CPP (C/C++)作者 (Alien)時間16年前 (2009/10/05 17:52), 編輯推噓4(4018)
留言22則, 3人參與, 最新討論串5/6 (看更多)
※ 引述《minazukimaya (水無月真夜)》之銘言: : : ◆ From: 114.32.15.163 : : → minazukimaya:好處是function call成本比較低啊 當然缺點就是靈活 10/05 16:50 : : → minazukimaya:度比較差 10/05 16:50 : : → adrianshum:最大問題是把本來的class 污染了, 用 external functor 10/05 16:52 : : → adrianshum:其中一個原因就是想改 sorting criteria 的時候不需改 10/05 16:52 : : → adrianshum:model, 但這做法, 每加一個就要改一次 model 10/05 16:53 : 加上getXXX()的做法也是每加一次要改一次model啊.. : 同樣都是汙染原本的class : 為什麼你為認為加十個getter比加一個template function汙染得少呢? : 要提取class其中的private成員 本來就勢必要在class裡面加東西 : 兩者的差別只在你加的是member function還是template member function而已 我本來的意思就是說, 你的做法是在加一堆 getXxx 呀. :) 我覺得比較好的做法, 就是根據 sorting criteria 不同 來寫不同的 functor. 本身 model 有提供方法去 access 內部資料的話, 這樣根本不必動到 model 本身. : : → adrianshum:根本和寫十個 compare_by_Xxx() compare_by_Yyy() 無異 10/05 16:53 : class LessThanByXXX { : public: : bool operator() (GNF& lhs,GNF& rhs) { return lhs.getXXX()<rhs.getXXX();} : }; : 這樣寫十個 和 : template <GNF::SortBy T> : class LessThanBy { : public: : bool operator() (GNF& lhs,GNF& rhs) { return lhs.getAttr<T>() < rhs.getAttr<T> ();} : } : 寫十個前者到底哪裡比較好.. 1) non-intrusive 2) 你本來的寫法, 只能以一個 field 來 sort 3) 容易理解 : 除了增加code的長度和降低維護性之外.. 增加的長度和你本來的 code 相比其實不多. 而維護性, 我個人覺得和你原本的相比沒有那裡有比 較低, 反而因為容易理解而更好維護. 有時候可維護 性和 code 長度未必成反比. 比如你的做法, sorting 的時候要 base on multiple field 的話 (相信我, 這非常常見, 非常 real-world), 就沒輒了, 除非弄一個 temp value object 再 override 其 < operator 才行. 但這種做法真的是好維護易明瞭嗎? : 寫十個functor然後每個functor只差9個字元 這樣真的比較好嗎 試用五個 field 的情況加上最簡單的使用 (沒有 我上面說的多field sorting) 比較一下, 是不是重覆得少? (我不太記得你的 code 了, 做個大概): 本來的 class: class Foo { private: int f1; int f2; int f3; int f4; int f5; public: // accessing methods } 你的方法: enum SortByAttr{ ATTR1, ATTR2, ATTR3, ATTR4, ATTR5 } class Foo { private: int f1; int f2; int f3; int f4; int f5; public: // accessing methods template<SortByAttr T> void getAttr() {}; template<> int getAttr<ATTR1>() { return f1; }; template<> int getAttr<ATTR2>() { return f2; }; template<> int getAttr<ATTR3>() { return f3; }; template<> int getAttr<ATTR4>() { return f4; }; template<> int getAttr<ATTR5>() { return f5; }; } template <Foo::SortByAttr T> class LessThanBy { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getAttr<T>() < rhs.getAttr<T>; } 我的寫法: (class Foo 沒變) class LessThanByF1 { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getF1() < rhs.getF1(); } class LessThanByF2 { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getF2() < rhs.getF2(); } class LessThanByF3 { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getF3() < rhs.getF3(); } class LessThanByF4 { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getF4() < rhs.getF4(); } class LessThanByF5 { public: bool operator() (Foo& lhs, Foo& rhs) { return lhs.getF5() < rhs.getF5(); } 除了那幾句基本 language constructs (class LessThanByFx, public:, oeprator().... ) logic 上根本沒有多少重覆的地方. code 也不見得比你的 做法長多少, 更何況你的做法也不是沒有重覆. 要加一個新的 sorting field, 你的做法要: 1) enum 加一個新 entry 2) 加一個template method 我的做法 (正常 field 會有 accessor 了) 只要加 一個 functor. 真的會比較難維護? 還有你裡面假定 1) 只用一個 attrib 做 sort 2) attrib 有適當的 < operator 反而令東西更難維護了. 像我上面所說, 假設想 sort by name, 所謂 sort by name 是先以 last name 再以 first name. 而 name 在 Foo 內是以 char* 存放 (非常正常合理的例子吧), 我只要在 functor 內寫好比較的方法就行吶, 可是你的做法呢? 或者 code 長度看來也還是會差不多, 但維護起來就差很遠了. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 202.155.236.82 ※ 編輯: adrianshum 來自: 202.155.236.82 (10/05 18:00)

10/05 18:04, , 1F
你把兩件事混在一起講了
10/05 18:04, 1F

10/05 18:05, , 2F
getter function是不是template 和
10/05 18:05, 2F

10/05 18:05, , 3F
comparator functor是不是template是兩回事
10/05 18:05, 3F

10/05 18:06, , 4F
另外原本的class是沒有getter的 不管你用哪種方法
10/05 18:06, 4F

10/05 18:06, , 5F
加getter進去都是汙染..
10/05 18:06, 5F

10/05 18:07, , 6F
作為 value object, 本身就有 getter 是很正常的, 可
10/05 18:07, 6F

10/05 18:07, , 7F
是你的做法, 除了本身 model 正常的 getter, 還要另外
10/05 18:07, 7F

10/05 18:08, , 8F
加這個為了 sorting 而生的 "另一堆 getter", 這就是
10/05 18:08, 8F

10/05 18:08, , 9F
我所謂 intrusive 的原因
10/05 18:08, 9F

10/05 18:09, , 10F
如果你說要額外加新的criteria,而這個criteria具有
10/05 18:09, 10F

10/05 18:10, , 11F
某種獨特性,那它就只會有一個 所以額外寫一個當然
10/05 18:10, 11F

10/05 18:10, , 12F
是不用template template幫你把十個functor壓縮成
10/05 18:10, 12F

10/05 18:10, , 13F
一個 但是沒說你所有的criteria都要寫進這個
10/05 18:10, 13F

10/05 18:10, , 14F
template裡
10/05 18:10, 14F

10/05 18:14, , 15F
也並沒有都要啊:P template 不是寫了什麼才生什麼嗎...
10/05 18:14, 15F

10/05 18:15, , 16F
問題就在於統一性了, 類似的情況要用不同的方法解決,
10/05 18:15, 16F

10/05 18:17, , 17F
維護起來當然變得困難 :) 我不否認你的做法是變有趣
10/05 18:17, 17F

10/05 18:17, , 18F
而在某些應用上是變實用的,只是用在這地方不太適合而已
10/05 18:17, 18F

10/05 18:22, , 19F
你現在在說的是哪個?getter function是template
10/05 18:22, 19F

10/05 18:22, , 20F
還是compare functor是template?
10/05 18:22, 20F

10/05 18:22, , 21F
前者的話討論在上一篇的推文 後者的話我完全不能同
10/05 18:22, 21F

10/05 18:22, , 22F
意用十個functor取代一個template functor是好做法
10/05 18:22, 22F
文章代碼(AID): #1AoS7BUZ (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1AoS7BUZ (C_and_CPP)