看板 C_and_CPP 關於我們 聯絡資訊
我承認有 re-develope ,不過主要是拿來練習用, 問題主要是 C 轉成 C++ 時,規劃很有問題。 另一個問題可能有得討論, 主要是 copy operator / constructor 帶來之 slide effect. 問題、敘述有點長,願拿出小弟一半 ptt 幣 (稅前 一萬 ) 以酬謝 ( http://ppt.cc/OCBA ) 問 題 敘 述 <前言> 首先,我練習用 C 寫大數演算法,目前在 C 裡面已可以成功做幾個功能 (1) 大數 (+ - * / %) 整數 (2) 大數 (+ - * / %) 大數 然後在過程中,我發現一般網路上給的範例,function prototype 其實沒給正確 (當然我相信可能是因為只是 sample code 而已), 導致 function 沒辦法複用。 拿減法而言,一般給的 protype : big_sub(int * A, int * B , int *C); /* C = A - B */ 然後 size 是一般就事先定義好的,不然就是包成 struct,總之 prototype 不會有多一個引數叫 int size,作為 target。 但很尷尬的是,目前小弟做的大數除法,較有效率的做法, prototype / caller 大概長這樣 big_sub(int * A , int * B, int * C , int size); /* prototype, C = A - B */ int R[r_size]; int A[DEF_SIZE], B[DEF_SIZE]; /* ...what ever... */ big_sub(A + c_len, R, B , r_len) /* caller */ 就是因為上面上面粉紅色的部份,所以導致 prototype 讓我想重新設計。 然後又考慮到有些運算我不需要是 C = A - B,而是 C-=B, 所以我又要多寫了 big_subs(int * A , int * B , int size); /* A-=B */ 轉到 C++ class 後,便是我地獄的開始... 問 題 敘 述 < Q1 轉到 C++ > 這裡我想先說一下 (我不確定後續發展有沒有關係), 我這份 class 打算做三個一樣的東西, 分別是 10 進位、萬進位、65536 進位, 然後陣列大小因為怕愈搞愈複雜,所以給的是固定大小的陣列 (不是 heap), 上述三個 class 就姑且稱 big10, big10000, big2n。 目前計畫是每個 class 都各自獨立,在寫 big10 的時候發現, 為了配合 operator + - * / ,所以這部份 prototype 根本不能塞 size 進去, 導致最後,原本在 C 寫好的 function, 全都塞到 class private 裡去,變成這樣 class ubig10{ private: int arr[100]; /* C style functions */ void c_big_add(int * A , int * B, int * C , int size); void c_big_adds(int * A , int * B, int size); void c_big_add_int(int * A, int B , int * C , int size); void c_big_adds_int(int * A, int B , int size); /* ...whatever... */ public: /* ... whatever ... */ /* friend every where */ friend ... friend ... }; oveload operator 是用 class member function, 不過一直在調用 C-style member function, 做成這樣讓我感覺很愚蠢,不知道是否有較佳之方案可解決? 然後, big10 / big10000 的部份 我在想 這麼做可能會較佳? template<int base=10 , int len = 4> class ubig10n{ /* ...what ever... */ }; 這樣到時候要 base-10 、base-10000 都可以很快搞出來 (吧) Q2 slide effect 我在網路上搜尋過一些各式各樣的 sample code (不專指大數), 然後 k 過手邊的書還是沒滿足我, 假設 class 裡有 heap 成員,最明顯的問題大概是長這樣吧 Class Class::func(const Class & A , Class & B){ Class tmpA(A) ; /* 不改 A , 暫存 A */ Class tmpB(B) ; /* B 需要兩份 */ /* ...whatever... */ return Class(tmpA - tmpB); } 這裡在 tmpA / tmpB 的地方可能沒辦法避開 constructor , 請問最後開銷是否是無法避免? (1) 先將 tmpA - tmpB 結果存下來,假設叫 tmpV (2) tmpV 再傳回去,呼叫 operator = , assigned to caller. 那如果另一個 member function 裡,有一段是這樣的話 void Class::func2(const Class & A, Class & B) { /* ...whatever... */ for(i=0; i<100; ++i) Class::func( A , B) /* ...whatever... */ } 這樣不就代表暫存變數 tmpA、tmpB 之生死循環了 100 次, 代表這 100 次經歷了 allocate、initialize value、release memory, 感覺很花費時間,所以,如果遇到這種情況的話, 將 func 直接 copy-paste 到 func2 裡面可以避開沒錯, 但萬一呼叫 func2~func20 都一直在裡面呼叫 func 的話呢? 也是一樣 copy-paste 解決?不知道我想法哪裡出了問題。 --------------------------------- 最後,謝謝各位耐心看完敘述,若上述敘述不清楚請點出, 我將再補充說明,謝謝各位先進不吝指導與賜教,感激不盡。 -- ~ 這輩子與神手無緣 我只好當神獸了 ~ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.76.161
loveme00835:class 是從 ADT(Abstract Data Type) 演變而來的, 你 12/17 02:48
loveme00835:的介面都不夠抽象, 所以轉換會難轉是一定的 12/17 02:49 請教這部份可以怎做才是所謂的 ADT ? typedef int Big[BIG_SIZE] ?? loveme00835:可以參考 std::move() 並實作 move ctor 12/17 02:52
loveme00835:以及 move assignment 12/17 02:55
這兩個我有找過一下,粗略似乎不是件容易事,或許 k 個有問題再發文較有效率些, 先謝謝 loveme00835 :)
legnaleurc:你在運算時要把"陣列"這個概念丟掉, 不然一定不夠抽象 12/17 13:48
legnaleurc:理想的大數類別應該是個數值型別, 也就是 int 能做的 12/17 13:50
legnaleurc:運算你都用同樣的 prototype 做就好了 12/17 13:50
legnaleurc:https://gist.github.com/619053 12/17 13:59
legnaleurc:之前給學弟練習 C++ 的範例, 隨便看看 12/17 14:00
我承認這裡有兩個 prototype 有點不懂 template< typename T > T to() const; /* 目的是 ? 轉型嗎? */ class Private; /* 這個我又更不懂了 */ 然後關鍵的 operator / 我沒在上面看到,代表這部份當時可能沒實作 ? 去掉 operator / 很好實作,做得出來真的也不是問題, 但考慮到 operator / 真的不是很好實作
EdisonX:可能我等一下先整理一下除法部份,再丟上來討論會好點吧. 12/17 16:35
這是 c code 部份 http://codepad.org/u2Z0mi3v 關鍵在於要 效率不要太差 時,大數還要回到 array 慢慢細思? 我承認 ADT 做很鳥,在轉 operator + - * 時很順沒錯 (和 legnaleurc 給的 class prototype 相仿) 但為了完成將 ubig10_div_v1 轉到 operator / 中間有用到的四個 function 還是要塞 size 為佳, 因過程中要做的可能是 A[7:2] -= B[10:5] 、類似的東西, 也就因為這層原因導致想不透怎轉過去 ※ 編輯: EdisonX 來自: 180.177.76.161 (12/17 17:34)
legnaleurc:就再加個 class 代表 num/den 就好啦 ... 12/17 18:31
legnaleurc:看不太懂你的 annotation 是什麼意思 12/17 18:36
EdisonX:先感謝 lovme00835 與 legnaleurc,其餘我找時間imple. :) 12/19 00:50