Re: [語法] Template與Inheritance結合??
※ 引述《clifftsai (嚕來嚕肥)》之銘言:
: template
: <
: class ThreadLock
: >
: class FSDB : ThreadLock
先看兩種大家都很熟悉的語法
┌───────────────────────────
│template < class T >
│class Foo
│{
│ T value ;
│} ;
└───────────────────────────
很單純的 class template,看你 T 給什麼型別,value 就是什麼型別。
┌───────────────────────────
│class Foo : Bar
│{
│ ...
│} ;
└───────────────────────────
很簡單的繼承,Foo 繼承 Bar,沒有指明繼承的形式表示是 private 繼承。
然後兩者合一
┌───────────────────────────
│template < class T >
│class Foo : T
│{
│ ...
│} ;
└───────────────────────────
看起來很玄,其實就是 Foo 繼承 T,
不過這個 T 是個 template,
看你 T 給什麼型別,Foo 就繼承什麼型別,
沒有指明繼承的形式表示是 private 繼承。
當你寫 Foo<A> 表示是一個 "Foo 繼承 A" 的型別
當你寫 Foo<B> 表示是一個 "Foo 繼承 B" 的型別
當你寫 Foo<C> 表示是一個 "Foo 繼承 C" 的型別
就是這樣。
Loki::Typelist 還有用到類似這樣的寫法
┌───────────────────────────
│template < class T, template <class> class U >
│Foo : T < U >
│{
│}
└───────────────────────────
這個 Foo 有兩個型別參數,
而且第一個型別必須是一個 class template,
Foo 繼承了 "T 以 U 具現" 這個型別,
看起來很酷,不過除了很酷以外,這可以幹嘛?
這可以用來實作 HierarchyGenerators 技術。
有的時候你需要一系列的 data member 跟是 member funciton
但是 template 在這個地方似乎就像個嬰兒一樣無能為力
這個時候你唯一的選擇好像就是複製貼上
舉個例子來說
我要設計一套影像處理類別庫
在設計一些基礎的影像類別的時候
我想要遵行「實作與介面分離的抽象性」
所以我不準備提供任何 public 的 data member
取而代之的是我準備為每個 data member 提供一個 function 來存取 data member
像這樣
┌───────────────────────────
│class RGB_Image
│{
│ private :
│ Array2D R_ ;
│ Array2D G_ ;
│ Array2D B_ ;
│ public :
│ Array2D & R() { return R_ ; }
│ Array2D & G() { return G_ ; }
│ Array2D & B() { return B_ ; }
│} ;
└───────────────────────────
然後當我準備設計另外一種影像類別的時候,例如 Lab
那就是這樣
┌───────────────────────────
│class Lab_Image
│{
│ private :
│ Array2D L_ ;
│ Array2D a_ ;
│ Array2D b_ ;
│ public :
│ Array2D & L() { return L_ ; }
│ Array2D & a() { return a_ ; }
│ Array2D & b() { return b_ ; }
│} ;
└───────────────────────────
然後我還要提供一種 YMCK 的影像類別
┌───────────────────────────
│class YMCK_Image
│{
│ private :
│ Array2D Y_ ;
│ Array2D M_ ;
│ Array2D C_ ;
│ Array2D K_ ;
│ public :
│ Array2D & Y() { return Y_ ; }
│ Array2D & M() { return M_ ; }
│ Array2D & C() { return C_ ; }
│ Array2D & K() { return K_ ; }
│} ;
└───────────────────────────
大家都是聰明人,已經發現到我在作重工,
這些千篇一律的白痴程式碼正在不斷腐蝕著程式設計師的腦細胞,
然後如果我還打算提供 HSV 或是其他等等等等的影像格式的話,
那我就要繼續這些重複性很高的智障程式碼。
其實複製貼上也不過就是按個兩下,沒什麼難,
問題是在於,手工的東西多了,錯誤的機會就會增加,
而且以後修改跟擴充的難度會比較高。
這些程式碼明明就有很高的重複性,
但是你好像沒辦法用 template 來解決這個問題。
事實上是可以的,
Loki::HierarchyGenerator 成功的利用 template 把這樣的程式碼生成機制自動化。
(HierarchyGenerator 有兩種)
我現在可以這樣做
┌───────────────────────────
│template < typenamep T >
│class Holder
│{
│ private: T value_ ;
│ public: T & value() { return value_ ; }
│} ;
│
│typedef TYPELIST_3 ( Array2D, Array2D, Array2D ) RGB_Typelist ;
│typedef TYPELIST_3 ( Array2D, Array2D, Array2D ) HSV_Typelist ;
│typedef TYPELIST_3 ( Array2D, Array2D, Array2D ) Lab_Typelist ;
│typedef TYPELIST_4 ( Array2D, Array2D, Array2D, Array2D ) YMCK_Typelist ;
│
│typedef Loki::GenScatterHierarchy < RGB_Typelist , Holder > RGB_Image ;
│typedef Loki::GenScatterHierarchy < HSV_Typelist , Holder > HSV_Image ;
│typedef Loki::GenScatterHierarchy < Lab_Typelist , Holder > Lab_Image ;
│typedef Loki::GenScatterHierarchy < YMCK_Typelist, Holder > YMCK_Image ;
└───────────────────────────
儘管很難相信,但我已經定義完這四種影像型別了,
每一個 class 都有該有的 data member 以及相對應用來存取的 member function,
而且之後每新增一種類別只需要多兩行程式碼來 typedef,
如果你覺得每次宣告物件的時候可以很勤勞的打上全名沒關係,
那連這兩行都可以省去。
你可以這樣存取每一個資料成員..
RGB_Image img ;
Loki::Field<0>(img).value() = ...
Loki::Field<1>(img).value() = ...
Loki::Field<2>(img).value() = ...
真是酷!
Loki::HierarchyGenerators 會根據你給的 Typelist,
(就是一串型別,像是這樣 int, int, double, Foo, Bar )
使用遞迴繼承自己的方法,
來讓最後一個類別擁有全部所需的 data member 跟 member function。
我這邊只是講一下他可以怎麼用,
實作細節有興趣的話可以看 《Modern C++ Design》。
-
感謝大家的指正跟補充 @@
HierarchyGenerator 只是 Typelist 一個主要的應用,
我把兩者混在一起是錯誤的。
另外我弄錯預設的繼承屬性真是天大的笑話 XD 抱歉萬分
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.113.129.180
※ 編輯: yoco315 來自: 140.113.129.180 (04/18 10:30)
推
04/18 10:41, , 1F
04/18 10:41, 1F
推
04/18 10:48, , 2F
04/18 10:48, 2F
推
04/18 11:21, , 3F
04/18 11:21, 3F
推
04/18 12:07, , 4F
04/18 12:07, 4F
推
04/18 13:12, , 5F
04/18 13:12, 5F
→
04/18 13:15, , 6F
04/18 13:15, 6F
推
04/18 13:57, , 7F
04/18 13:57, 7F
※ 編輯: yoco315 來自: 140.113.129.180 (04/18 18:28)
推
04/18 23:24, , 8F
04/18 23:24, 8F
推
04/19 00:20, , 9F
04/19 00:20, 9F
討論串 (同標題文章)
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章