[已解] From C to C++

看板C_and_CPP作者 (藍影)時間14年前 (2011/10/25 19:27), 編輯推噓8(8048)
留言56則, 8人參與, 最新討論串1/1
希望這問題不會引起討伐。一些因素,我要編一些講義, 主要引導本身熟 C language,想快速學 C++ ( 只有簡單 OO , 不含 STL ) 者 , 前言就略掉,以下提出本身在 search 後,仍存有的疑問。 問題有點多、雜,不奢求全都回答,只挑部份回答,或願給 website 也很感激! Q1 : new 與 malloc 差異很大,除了一個是運算子,另一個是函式外,配置失敗之處理也不同, 從一些較經典之書上也得知,new / malloc , delete / free 不可混用, 我的問題是,對於 POD 而言,若用 new 後, 後續是否可以 mem~ 或 str~ 相關函式進行操作 ? 如 memcpy、memset、strcpy、strncpy 等,或這部份只適合以 algorithm 之 copy、fill、fill_n 方式處理為佳? ( 也想追問這兩套的效率, 雖覺得這在 OO 可能不會是太大重點 XD ) Q2 : 能否跳脫一般 C++ 書籍架構 class 使用之函式 ? 在小型專案中,大多都是寫一、二個 class 就搞完了, 在寫 class 時,沒有書籍拿 c library 的東西在寫 class, 過去小弟是一律用 c library 在做 class 處理,認為這對處理 POD 而言也算合理, 以 IO 而言,即使全用 printf、fprintf、scanf、fscanf 似乎也沒影響 , 不知上述之處理是否也算合理? Q3 : function pointer 取代方案 目前想到最有問題的應該這部份,直接看碼 double fitness(double x, double y) {return sin(x)*sin(y)*sqrt(fabs(x*y));} typedef double (*pFunc)(double x, double y); class Foo{ private : pFunc mFunc; double mx, my; public : inline void SetFunction(pFunc func) {mFunc = func;} }; 上面 SetFunction 這段會造成 compile error, 目前想到的解決方案是 (1) 將 fitness 直接設成 friend function. (2) 將 fitness 直接寫到 Foo 裡面,設 private. 但上述這兩種方式都要再動到 Foo , 較希望的是 , 不去動 Foo 情況下 , 直接將一個 data member , points to function , 不知能否達成? --- 以上,謝謝各位不吝指導,感激不盡。 -- No matter how gifted you are, alone, can not change the world. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.78.41

10/25 19:50, , 1F
想請教Q3是那一個compiler編不過呢?
10/25 19:50, 1F
確認過,我似乎是誤會了一些東西。全擠在同一個 main.cpp 裡面是沒問題 但拆開來寫會找不到 fitness function, http://codepad.org/Kvijz3gg 再到 myTest.h / myTest.cpp 做宣告動作仍沒解掉 (可能 scope 那裡觀念不對) 像這樣 http://codepad.org/2Kbn8YJu , still fail Orz. 或這種 函式/檔案 分配模式並不佳? 懇請解惑。 compiler : Visual C++ 2008 , error msg : fatal error LNK1120: 1 個無法解析的外部符號

10/25 20:31, , 2F
關於第二點我的想法是覺得class只是oo的一個東西,oo
10/25 20:31, 2F

10/25 20:31, , 3F
也只是一個概念,至於裡面實作使用c或c++應該不是太
10/25 20:31, 3F

10/25 20:32, , 4F
大的問題,c或c++都會有對於實作上有較好的支援,
10/25 20:32, 4F

10/25 20:32, , 5F
當然是使用較好的了,至於io部份,是有看過文章說
10/25 20:32, 5F

10/25 20:33, , 6F
c的io比較快速,但應該還好,我個人是會c與c++的io混
10/25 20:33, 6F

10/25 20:34, , 7F
著用,如果想要方便就用c++的,想要格式化就用c的
10/25 20:34, 7F

10/25 20:34, , 8F
一點小小的拙見
10/25 20:34, 8F

10/25 20:44, , 9F
對於q1可以參考http://ppt.cc/dGBJ
10/25 20:44, 9F

10/25 20:45, , 10F
http://ppt.cc/_P5X 看來答案是都可以,但提到了一
10/25 20:45, 10F

10/25 20:45, , 11F
個想法, 還不錯~
10/25 20:45, 11F
謝謝提供訊息, Q1 那裡真是算是 Big Problem, 再次感謝 *^_^*

10/25 21:14, , 12F
Q3: 先把inline拿掉編看看
10/25 21:14, 12F

10/25 21:18, , 13F
如果大概了解了在麻煩t大分享了xdd
10/25 21:18, 13F

10/25 21:18, , 14F
這三個問題都滿有意思的啊!
10/25 21:18, 14F
diabloevagto 大給的 link 真的不錯, 都有解答了。 Q1 : new 與 malloc 若是 POD 的話真的沒差,但若討論效率的話,應是看 compiler 在 algorithm 那裡 怎麼實作, 對於 POD 的話一些 compiler 可能會偷調 memcpy / memset 之類的函式, 甚至可能實作效果比 memcpy / memset 還快。但 malloc 只能用在 POD , 若用在一 些 class object, 因建構子關係,必須使用 new 運算子, 用 malloc 去配物件的話會 導致在 heap 上之物件跳過 建構 這程序。 Q2 : 能否跳脫一般 C++ 書籍架構 class 使用之函式 ? 目前這點的確多數人想法不脛而同。OO 是一概念,也非使用 cin/cout 就是 C++, 對有需要快速以 C 去跨入 simple OO , POD 下全以 C library 也無不可。 Q3 : function pointer 取代方案 這點純粹是我腦殘 Orz , 完全忽視了 inline 實質意義 , 還曾天真的做了 typedef inline double (*pFunc)(double, double); 這動作 , 各推文所述無誤,是 inline 問題。 是上面這東西若堅持要用 function pointer 傳入,勢必放棄 inline 型式。

10/25 21:30, , 15F
Q3確定是Cal inline的問題,拿掉就會過了。
10/25 21:30, 15F

10/25 21:34, , 16F
真的全拿掉就過了!! function pointer 似乎不適合用
10/25 21:34, 16F

10/25 21:34, , 17F
inline. (應說不能).
10/25 21:34, 17F

10/25 21:35, , 18F
看不到程式碼就不是inline了, 你可以寫在class body裡, 或
10/25 21:35, 18F

10/25 21:36, , 19F
是拿出來, 但是編caller看不到定義就不能inline
10/25 21:36, 19F

10/25 21:39, , 20F
10/25 21:39, 20F
這篇寫得不錯,謝謝 p 大! *^_^*

10/25 21:42, , 21F
不知主流的高階語言裡,有類似 inline 機制的多不多,好奇
10/25 21:42, 21F
沒記錯的話, M$ CLR (.net, 含 VB,C#,F#,) 有引入這概念 (但早期 VB 6.0 沒有), 特性沒什麼兩樣,其它程式語言可能要另請高人。

10/25 21:42, , 22F
Q1:如果你的class只有成員變數.沒有函式的話.用mem~
10/25 21:42, 22F

10/25 21:42, , 23F
也沒什麼關係.不過你忘記str~系列,只有處理char *問題
10/25 21:42, 23F

10/25 21:44, , 24F
或是new int/double/char* 這樣單純的型態.其實都沒差
10/25 21:44, 24F
str~系列應是我沒說我接下來要做什麼的關係,我打算實作 M$-ATL CString class 做為範例,用 mem~ 系列處理 「有時」 不比 str~ 系列處理洽當,下次會額外提出。 最後還是感謝您寶貴的意見, 謝謝。 *^_^*

10/25 21:47, , 25F
使用algorithm系列比較好處理自訂的class(有成員變數和
10/25 21:47, 25F

10/25 21:48, , 26F
函式)的,當然用algorithm去處理.c的函式處理較快
10/25 21:48, 26F

10/25 21:49, , 27F
c++演算法的函式有考量到例外處理和模板等.會犧牲掉一些
10/25 21:49, 27F

10/25 21:50, , 28F
速度.
10/25 21:50, 28F

10/25 21:52, , 29F
Q2的問題依舊是效率問題,通常c的處理會比較快.所以在
10/25 21:52, 29F

10/25 21:53, , 30F
一些c++專案中,會發現extern c{...},裡面使用一些純c
10/25 21:53, 30F

10/25 21:54, , 31F
去處理效率問題.至於Q3.你應該是把inline放在實作檔去定
10/25 21:54, 31F

10/25 21:55, , 32F
義.而不是放在標頭檔的函式宣告.(應該是這樣)
10/25 21:55, 32F

10/25 22:10, , 33F
1. 不管有無inline都可以使用function pointer
10/25 22:10, 33F

10/25 22:11, , 34F
2. 使用 algorithm 有時反而更快,比如說 std::sort
10/25 22:11, 34F

10/25 22:12, , 35F
3. extern "C" 只是定義函式的界面,與效率無關
10/25 22:12, 35F

10/25 22:12, , 36F
使用 C 界面的函式依然可以用 C++ 實作
10/25 22:12, 36F

10/25 22:13, , 37F
thanks
10/25 22:13, 37F

10/25 22:19, , 38F
最後,inline這個關鍵字是為了C++這種分離.h的語言而設
10/25 22:19, 38F

10/25 22:20, , 39F
像c#或java這種界面和實作寫在一起的語言
10/25 22:20, 39F

10/25 22:20, , 40F
編譯的時候compiler有足夠的資訊自行判斷是否要inline
10/25 22:20, 40F

10/25 22:21, , 41F
所以沒必要另外要求programmer手動標示
10/25 22:21, 41F

10/25 22:27, , 42F
另一方面,C++ compiler在閱讀.h時,並不知道這是個.h
10/25 22:27, 42F

10/25 22:27, , 43F
(因為compiler讀進來的是經過preprocessor的處理結果)
10/25 22:27, 43F

10/25 22:29, , 44F
所以有必要透過inline來標示函式為weak linkage
10/25 22:29, 44F

10/25 22:27, , 45F
@littleshan: inline 那裡覺得怪怪的
10/25 22:27, 45F

10/25 22:28, , 46F
http://ppt.cc/CSfB 這樣可以讓 fitness 維持 inline
10/25 22:28, 46F

10/25 22:29, , 47F
讓 Foo 用嗎 ? http://www.FunP.Net/62 -> 程式碼下載
10/25 22:29, 47F
補齊。

10/25 22:34, , 48F
這個錯誤與 function pointer 完全無關
10/25 22:34, 48F

10/25 22:37, , 49F
C++ std 3.2p3: An inline function shall be defined
10/25 22:37, 49F

10/25 22:37, , 50F
in every translation unit in which it is used.
10/25 22:37, 50F

10/25 22:40, , 51F
!! 上面兩段出來清楚多了,感謝。
10/25 22:40, 51F
※ 編輯: tropical72 來自: 180.177.78.41 (10/25 22:56)

10/25 23:01, , 52F
另外寫一個類別再重載operator()(有可能加速), 或是其他方
10/25 23:01, 52F

10/25 23:01, , 53F
10/25 23:01, 53F

10/25 23:37, , 54F
謝謝 poyenc 大給的 link, 我再好好 K 過, 感謝 *^_^*
10/25 23:37, 54F

10/26 09:12, , 55F
Q1:str~系列的函式,只有單單處理字串. 而我一開始的意思
10/26 09:12, 55F

10/26 09:14, , 56F
是我以為你要用strcpy去處理物件.因此才提出這疑問
10/26 09:14, 56F
文章代碼(AID): #1EffqffE (C_and_CPP)