看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《Ebergies (火神)》之銘言: : 這麼說好了,前文的 Header 大概如下 : // b.h : class A; : class B { : A *obj_a; : public: : void do_something(); : A *do_something_with( A *a); : }; : 你有幾點訴求 : 1) 效率 : 2) 可讀性 : 2.1) 典型的重複程式 : 2.2) 從介面來看, 傳址不改值 and 傳參考卻會改值, 呼叫端的閱讀也會不利 [deleted] 我對 reference 與 pointer 之爭沒興趣 但其實 A *obj_a 與 A obj_a 在閱讀的時候是有滿大的不同 class B { A obj_a; ... } 以上這種情況型塑的是很清楚的 B has-a A obj_a 在 B object 建立時跟著被建立 而且在 B object 解構時跟著被解構 A *obj_a 呢?這可能性就很多了 它可能只是另一個生命週期與 B 完全無關的物件 也可能根本指向 NULL 所以如果要型塑 has-a 的關係 我會先使用 A obj_a 的方式 除非 compile 速度慢到讓人受不了再去用 pimpl 統一解決 : 好吧,最後談到效率 : 的確很多時候透過指標取值的效率會有點差異 : 但是或許還有另一點值得注意 : 就是複製整個複雜的 structure 遠比複製指標還慢 : 一般的情況下連 string 這種小東西都有人建議多使用 const string &s 取值了 : 而通常我們都能夠分辨哪些東西是夠小,夠常被存取的東西 : 哪些東西是很大,我們不常重複的存取整份資料的東西 : (Managed C++ 把它們分為 value class/ ref class) : (或者你也可以用 struct 與 class 區分它們) : 而就我的經驗,使用 pointer 的機會應該遠比直接存取變數情況要多得多 : 當然,那些情況使用 pointer 的效率比較好,程式碼也比較單純 : 尤其是在使用 vector 將你的 class 裝起來的時候 效率上來說 若把具有 has-a 關係的成員宣告為 pointer 代表你在建構式中需要呼叫 new 來為它配置記憶體 因此建構物件時會明顯比較慢 class B { A* obj_a; public: B() : obj_a(new A) {} ~B() { delete obj_a; } }; void foo() { B b; // 需額外執行一次 new for(int i = 0; i < 10; ++i){ // 迴圈額外執行了十次 new B b; ... } } 如果你把 obj_a 宣告為 A 這些 new 的時間成本都會消失 因為在 stack 上配置物件的空間基本上是零成本的 除非說 A 的建構式自己會去呼叫 new 另外如果 B has-a A object 那麼把 obj_a 宣告為指標並不能增加複製物件的效率 class B { A* obj_a; public: void assign_a(A* obj) { delete obj_a; obj_a = obj; // 通常不能這樣寫 } }; 因為 B has-a A 意味著 B 在解構時也會負責把 obj_A 解構 因此在進行 assignment 時也要一併進行所有權的轉移 比如下列的 code 會造成 runtime error: void foo(){ A some_obj; B b; b.assign_a(&some_obj); }; 所以你要嘛就是在 assign_a 裡面自己做一次 copy 不然就是在呼叫 assign_a 之前自己用 new 來複製一份 (不過第二個方法不好...誰知道 B 的解構式是不是用 delete 來解構 obj_a 呢?) 只要 B 與 A 的關係是 has-a 那針對 obj_a 的 assignment 是無法避免地要複製所有 A 的內容 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.168.87.243 ※ 編輯: littleshan 來自: 118.168.87.243 (04/09 02:38)
loveme00835:執著於語法的差異, relationship 倒是忘得一乾二淨 04/09 02:39