Re: [問題] C++ 不能像 Java 一樣,完全避掉 pointe …

看板C_and_CPP作者 (cppOrz)時間18年前 (2005/11/26 03:11), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串2/2 (看更多)
※ 引述《eliang ()》之銘言: : 我自己在寫程式的時候, 對於 reference 和 pointer 的選擇方式是: : 「盡量使用 reference, 不能用 reference 時才用 pointer」 這是個好習慣。不過個人的建議是,在 C++ 中,最好是把兩者都當作 基本語彙,不要刻意去避免而扭曲語法,自然就好。 舉個例子: X *p = new X; 你也可以寫成 X &r = *new X; 但後者並沒有什麼好處。 : 可是這樣會造成整體不一致, 因為有地方用 reference, 有地方用 pointer, : 寫程式時常常會搞不清楚當初宣告的型別是什麼, 而要回頭去查前面的程式碼, 一些 IDE 或編程環境可以輔助這個問題,不過「回頭查」並沒有麻煩到哪裏去。 以介面設計來說,傳遞(參數或回傳值)reference 或 pointer 的取捨,主要 考量在於其值是否可能為 Null,如果有可能為 Null 就用 pointer,反之則用 reference,例如: struct C1 { C1(X const * =0); // 建立 C1 物件可要可不要某個 pointer to X 物件 ... }; struct C2 { C2(Y const &); // 建立 C2 物件必須參照某個 Y 物件 ... }; X *fooX(); // fooX 可能回傳空值 Y &fooY(); // fooY 回傳某個 reference to Y 物件 : 想學 Java 完全都使用 reference 也不行, 因為以下用法都不合法: : int& a[10]; // 10 個 int 的 reference, 可以分別參考 10 個 int : vector<int&> b; // 元素為 int& 的動態陣列 : 結論是: : reference 和 pointer 混用 -> 一致性差, 造成寫程式不方便 : 完全使用 reference -> 行不通 : 那麼是不是乾脆一律用 pointer 還比較好? : 請問大家是怎麼選擇的? 有兩點應該要澄清。 首先,reference 和 pointer 不僅在語法上和語意上有所不同(主要差別在 於 pointer 帶有變量的特性),例如前面的例子,所以何來「一致性差」的 問題?大約只能說,reference 在某些情況下可以取代 pointer,而當兩者都 適用時,reference 的語意範圍較窄,且在語法上比較簡潔,因而在此情況下 「儘量用 reference」是好習慣。 (X & 的語意近似 X * const,也就是捨棄 pointer 帶有變量的特性,且在 建立時,就必須完成初始化的動作;當然細微處仍有不同,例如 X * const 可以接受 0 值讓其他模組作檢查。語法上則自然以 reference 較簡潔。) 其次,C++ reference 和 pointer 的機制,在內部都有額外的配置耗用,所以: void foo(X); void foo(X const &); void foo(X const *); 以上三種寫法,如果 X 是某個 sizeof 不大於指標所佔空間的基本型別(例如 int),寫成後兩種並不會比第一種更有效率,所以某些講求效能的程式庫,其 所提供的 template 代碼,還會提供靜態型別選擇的機制,來作為優化(當 X 是基本型別用第一種,否則用第二種)。 同理,Java 的設計也一樣,它針對基本型別,例如 int,和 C++ 一樣是採取 「傳值」的語意,也就是在參數或回傳值傳遞時,是會自動產生一個複本的。 只有對使用者自訂型別,是採取內建式的「reference」語意。(並非如你所謂 的「Java 完全使用 reference」) 所以,假如 X 的型別是 int 的話,寫 vector<X &> 不如直接寫成 vector<X> ,後者不但簡潔,執行效率還比較快。 當然 vector<X&> 是錯的,當 X 不是基本型別時,為了效率考量,在 C++ 中 一般是用 vector<X*> 來取代;或者透過一個代理類別: class X { ... }; typedef boost::shared_ptr<X> XRef; 接下來使用 vector<XRef>,就和 Java 的慣用法差不多了。 至於 Array,也是透過一個代理容器: boost::shared_array<X> Array(new X[n]); 好處是在多數場合(尤其是 sizeof(X) / sizeof(XRef) 比值不大時),效率上 比 vector<XRef> 佔優勢。(但 vector 優點在於彈性和延伸性) 但總之,不論 Java 內部是怎麼實現的,也不可能會是: X &x[n] 或 vector<X &> 這種東西。 C/C++ 遵循「傳值」語意,使用 pointer 或 reference 由用戶自決;Java 的 reference 語意是內建設施(但不包括基本型別),用戶是沒得選的。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.120.214.120 ※ 編輯: cppOrz 來自: 59.120.214.120 (11/26 05:15)

11/26 16:00, , 1F
太感謝了:)
11/26 16:00, 1F
文章代碼(AID): #13Xs76PB (C_and_CPP)
文章代碼(AID): #13Xs76PB (C_and_CPP)