看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) ubuntu gcc c++11 問題(Question): 寫類神經網路的時候時常要把層轉型 想問把cast寫成macro會不會太偷懶 或是有更好的做法 *[36m程式碼(Code):(請善用置底文網頁, 記得排版) *[m //定義 class BaseLayer{}; class InputLayer : public BaseLayer{}; class HiddenLayer : public BaseLayer{}; class OutputLayer : public BaseLayer{}; //把層轉成Base存在vector std::vector<BaseLayer*> Network; Network.push_back(new InputLayer(args) ); Network.push_back(new HiddenLayer(args) ); Network.push_back(new OutputLayer(args) ); //要調用的時候就得 static_cast<InputLayer*>(Network[0])->input = GetInput(); static_cast<HiddenLayer*>(Network[1])->DoSomething; static_cast<OutputLayer*>(Network.back())->output; 現在打算定義macro 讓事情簡單一點 #define GET_INPUT( x ) static_cast<InputLayer*>( (x)[0] ) #define GET_HIDDEN( x , i ) static_cast<HiddenLayer*>( (x)[(i)] ) #define GET_OUTPUT( x ) static_cast<OutputLayer*>( (x).back() ) 這樣調用只需要,看起來也比較清楚 GET_INPUT( Network )->DoSomething; ... 而且本來Network也不只是個vector 實際用起來會在多一層 比較難看 補充說明(Supplement): c++11 以上的方法也可以 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 61.227.156.4 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1469376591.A.71E.html
Caesar08: 你確定你很清楚,繼承、virtual function這些東西嗎? 07/25 00:54
我現在把virtual function 理解成function pointer, 繼承像是結構包結構,只是調用function的時候會根據type轉換this 我在base裡面只有解構是virtual 其實寫的有點抖,沒很確定理解有沒有錯
Caesar08: 另外,依照你現在貼的code,用unique_ptr會好很多 07/25 00:56
※ 編輯: grayStone (61.227.156.4), 07/25/2016 01:05:01 unique_ptr好像不能直接static_cast成我要的物件 得放棄做一個新的,或是move過去? 主要是擔心效率問題,不然unique_ptr好多了,還不用怕delete錯type ※ 編輯: grayStone (61.227.156.4), 07/25/2016 01:09:36
ilikekotomi: BaseLayer加個DoSomething的Pure virtual function 07/25 01:07
ilikekotomi: 之後再override BaseLayer的DoSomething就不用轉型了 07/25 01:09
我大部分需要轉型都是要存取不一樣type自己的成員,而不是DoSomething()
Caesar08: 那這樣你應該先去讀一下什麼是virtual function 07/25 01:11
立刻去看 ※ 編輯: grayStone (61.227.156.4), 07/25/2016 01:14:16
Caesar08: unique_ptr跟raw pointer效能一樣(shared_ptr就不是) 07/25 01:12
Caesar08: 你用virtual function所降低的效能還比較大 07/25 01:13
Caesar08: 不過virtual function的效能影響也很低就是了啦 07/25 01:13
了解, 查了virtual function 多了查詢vtable的動作
ilikekotomi: Sorry 沒看仔細 DoSomething直覺是function 07/25 01:26
是我該抱歉沒寫清楚,修一下說明
yoco: 唸一下什麼是 virtual function,可以解決你的問題 07/25 01:51
yoco: 然後你都要算神經網路了,效能瓶頸不會在 smart ptr 這邊 07/25 01:52
被你這句話打醒,的確效能不會是這裡的問題, 但我是需要存取每層不同的成員才轉型,virtual function可能不能直接解決 現在打算照C大的建議改成unique_ptr 只會多很多類似下面這樣的程式碼 auto i = unique_ptr<InputLayer>( static_cast<InputLayer*>( Network[0].release() ) ); i->input = GetInput(); Nerwork[0] = move( i ); 要把東西cast過才能存成員,然後要裝回去,希望除了整個重構以外還有比較直接的方法 ※ 編輯: grayStone (61.227.156.4), 07/25/2016 03:35:45 ※ 編輯: grayStone (61.227.156.4), 07/25/2016 03:37:02
steve1012: Virtual 不是就直接解決了嗎 你知道啥是多型嗎 07/25 06:08
steve1012: 歹勢剛沒看到推文 原來不是function 那你可以講一下你 07/25 06:12
steve1012: 的class 架構 比較好給意見 07/25 06:12
steve1012: 話說直接把do something包成function 呢? 把static ca 07/25 06:14
steve1012: st放裡面 07/25 06:14
steve1012: 話說為甚麼要把input output 一起放進vector 你這三種l 07/25 08:00
steve1012: ayer用繼承的時候有甚麼目的嗎 只有virtual destructor 07/25 08:00
steve1012: 感覺沒必要用多型 可能要稍微講一下你class的架構比較 07/25 08:00
steve1012: 好 07/25 08:00
我的hidden還有output還多繼承了一個計算層,input只是放資料的 class CalcualteLayer : public BaseLayer{}; 都放vector目的是 1.存一起看起來比較簡潔 2.層可能會替換算法,例如多一種class OutputLayer_Type2 : public CalculateLayer 都放一起的好處就是我不用修改訓練網路的class,只要轉型成CalculateLayer 然後寫個for去跑訓練就好 整個架構大概是 class base // data member class calc : public base // virtual calc function , data member class input : public base class hidden : public calc // calc function class output : public calc // calc function , output function, data member class network{ vector<base*> }; //network training function 或許我需要的是去多看幾本書 design pattern? ※ 編輯: grayStone (1.175.176.116), 07/25/2016 20:46:01
steve1012: 那input 為啥要跟另外兩種放在一起? 要做計算應該只有 07/25 21:38
steve1012: 後面兩種layer? 07/25 21:38
hylkevin: 要用dynamic_cast才對 不然資料怎麼錯的你都不知道 08/02 00:51