Re: [問題] 問一個新手問題

看板java作者 (godfat 真常)時間17年前 (2008/03/27 18:37), 編輯推噓3(301)
留言4則, 2人參與, 最新討論串12/14 (看更多)
很久沒寫點什麼了(或是說都沒貼過來),就在 java 板講點 c++ 的廢話吧... @_@b 當然也只是一些個人的理解就是了... ※ 引述《PsMonkey (痞子軍團團長)》之銘言: : 而 c++ 似乎沒有這樣分,反正 method 有在 class 宣告就好 : 有沒有在 class 裡頭 define 沒關係,也許某個檔案的某個角落就有實做 : 你必須自己去尋找、分辨 : 我是不知道 c++ 這樣作有什麼好處, : 也許高手可以用這個模糊地帶玩出一些方便開發的優點 : 我是懶惰的遜咖,害怕這種事情... 其實這樣做的原因很多,並不單單只是因為「好」或是「習慣」。 就像我在前幾篇的推文提到的,這樣作比較大的原因是來自 compilation model. 由於 c/c++ 遠比 java 靜態,他在編譯的時候就需要各個 class/function 的 原始資料,也就是 source code. 然而我們需要的其實只有 declaration, 並不需要 definition. 所以很自然地就把 declaration 放在 header, 並讓其他 source code 去 include 進來。也就是說,每個 compilation unit 都會需要所有用到的 class/function 的 declaration. (不過其實 class header 就已經是 class definition 了,但這邊先不分這麼細) 於是當我們提供自己的 library 時,可以提供 binary + header 即可, 對方可以完全不用看到實作細節到底是怎麼樣。這樣一來可以隱藏實作細節, 二來有人不想 open source 卻要作 library, 就能用這種方式。 然而 java 這部份的資料完全是動態載入的,所以就不需要 header, 更不會有恐怖的 circular dependency? 其實我不確定,java 不常寫 @_@ 不過剛剛試了一下,確實可以搞出有趣的東西... a.java: class A{ B b; } b.java: class B{ A a; int d; } 這樣一開始是沒辦法編譯的,但是可以先把 class A 的 B b; 拿掉, 隨便做出個錯誤的 A.class, 接著 compile b.java, 再把 a.java 加回 B b; 並編譯。 另外寫了個 c.java: class C{ public static void main(String[] argv){ A a = new A(); B b = new B(); a.b = b; b.a = a; a.b.a.b.d = 10; System.out.println(b.a.b.a.b.d); } } 這樣剛剛測試是可以跑出 10 的... 小實驗中沒問題,大程式這樣會不會掛我就不知道了...? 有請熟悉 java compilation model 的 @_@b 而在 c/c++ 中理所當然不能搞這種事,因為 header 就等於是 spec, 如果讓兩個 binary 中得到的資訊不同,我想程式在 runtime crash 掉的可能性很高 於是有了 forward declaration 與 declaration 和 definition 分離這兩件事, 使得可以寫成這樣: a.h: #ifndef _A_H_ #define _A_H_ class B; // 宣告,沒有定義 class A{ public: B* b; void f(); // 宣告,沒有定義。因為如果在這定義,不能使用還沒定義的 B! }; #endif b.h: #ifndef _B_H_ #define _B_H_ class A; class B{ public: A* a; int d; }; #endif 而這同時也是因為 #include 只是作 text 上的處理,不是什麼模組化的東西。 當然不可能在 a.h 去 include b.h 然後 b.h 又去 include a.h... 所以至少 A 或 B 其中一個一定會看不到對方真正的「定義」。 但是如果「宣告」和「定義」分離了,那麼就能讓 A 和 B 互相使用對方的東西... 這跟 OO 無關,也不是說宣告和定義分離會特別好用,只是 c/c++ 的 compilation model 需要這種分離才能做到某些事情。如果沒有碰到上面那種事情, 要全部的東西都寫在 header 也不是不行,小心 multiple definition 就好了。 也就是說 c++ 其實沒什麼良好的模組化能力。有人在 c++0x, 也就是下一版的 c++ 中提出相關的 proposal, 我沒記錯的話是沒有通過的。原因我想很簡單, 這影響層面太大了.... 而 09 年又只是明年 XD 另一方面,如果你「信任」對方的話,只看宣告和文件也會比看到一堆定義來得清楚。 雖然說其實現在編輯器這麼強大,要把所有定義 fold 起來,讓 *.java 看起來像 *.h 那樣只有宣告的「樣子」,也不是什麼大問題... btw, 如果再談到 c++ template, 那情況就會變得很恐怖了。恐怖在於原本的宣告和 定義分離,某種程度上會無法作用。這時候就要靠只有 comeau 實作的 export 了... 然後其他 c++ compiler 全部都會無法編譯... 除非要手動去 instantiate... 越靜態的東西,編譯起來就越麻煩... -- 生死去来、棚頭傀儡、一線断時、落落磊磊 《花鏡》-世阿弥 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.135.28.18

03/28 12:49, , 1F
又多學到了一些東西!
03/28 12:49, 1F

03/28 18:28, , 2F
這篇寫得好,早看到我就不用多嘴了 :)
03/28 18:28, 2F

03/28 18:34, , 3F
現實上要共用的東西都不該弄成C++的形式,問題太多了
03/28 18:34, 3F

03/28 18:37, , 4F
除非是 open source 的型式...
03/28 18:37, 4F
文章代碼(AID): #17wtZM5h (java)
討論串 (同標題文章)
文章代碼(AID): #17wtZM5h (java)