Re: [問題] c++ 的物件使用一問

看板C_and_CPP (C/C++)作者 (godfat 真常)時間19年前 (2006/02/09 02:52), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串3/3 (看更多)
......先行聲明,以下內容大多出自於猜測 如有錯誤希望大家可以出聲指正,以免造成誤導與混淆 :( : ======================== : 你的問題其實只有一個關鍵: : ic::ic(src& s) : 接受的是 non-const reference : 你傳暫時物件進去,那就等於傳 const 物件了,這樣當然會錯囉 : 否則你可以試試把 ic(src& s) 參數改成 const src &s 看看 : 就可以運作了 : 函式的 reference 參數 : 如果沒加 const,就表示接收進來的物件可能被修改 : 所以如果有傳入暫時物件的可能,一定要加 const : ========== 我覺得不太像是這個問題,我寫幾個測試 code 根據原 po 的問題改編,g++ 3.4.2 得錯誤訊息 error: no matching function for call to `DerivedA::DerivedA(Derived A(&)(DerivedB))' note: candidates are: DerivedA::DerivedA(const DerivedA&) note: DerivedA::DerivedA(const Base&) struct Base{Base(){}}; struct DerivedA: public Base{ DerivedA(const Base&){} DerivedA(const DerivedA&){} }; struct DerivedB: public Base{ DerivedB(){} DerivedB(const Base&){} }; int main(){ DerivedA a(Base()); DerivedA b(DerivedB(a)); DerivedA c(b); // at this line } b 是一個普通的 DerivedA 物件,可是 const DerivedA& 和 const Base& 都不吃 根據錯誤訊息,b 的型別是 Derived A(&)(DerivedB) 再來看 Comeau C++ 4.3.3 的錯誤訊息: (from: http://www.comeaucomputing.com/tryitout/) (btw, 我好想買喔) error: no instance of constructor "DerivedA::DerivedA" matches the argument list The argument types that you used are: (DerivedA (DerivedB)) DerivedA c(b); ^ 也就是說,他認為 b 的型別是 DerivedA (DerivedB) 了 把上述 code 做一點修正: 把 struct DerivedA 移到 DerivedB 下面 在 DerivedA 裡追加一個 c'tor 叫 DerivedA(const DerivedA(DerivedB)){} (模仿 Comeau 的型別) 在 g++ 下,再得錯誤訊息:(我只列改變) note: candidates are: DerivedA::DerivedA(const DerivedA(*)(DerivedB)) <near match> ... 看到 g++ 的提示,near match...(差一個 const) 而 Comeau 的 compile 結果呢? 很抱歉,還是 error, 不過給的錯誤訊息沒有任何改變 (這點就覺得 g++ 錯誤訊息比較方便了… 有時候看不懂的型別就 compile 沒差,反正會告訴你) 再改一次,這次加個 & DerivedA(const DerivedA& (DerivedB)){} 錯誤訊息: note: candidates are: DerivedA::DerivedA(const DerivedA&(*)(DerivedB)) <near match> ... 這次改成 g++ 的提示: DerivedA(const DerivedA(&)(DerivedB)){} 這樣…還是不能通過編譯 note: candidates are: DerivedA::DerivedA(const DerivedA(&)(DerivedB)) ... 這次連 <near match> 都沒給了 把 const 拿掉,變成: DerivedA(DerivedA(&)(DerivedB)){} 這下終於順利通過 compile 了,g++ 和 comeau 都一樣 而如果改成這樣: DerivedA(DerivedA(DerivedB)){} 其實也可以通過編譯,同樣 g++ 和 comeau 都一樣 這樣也可以: DerivedA(DerivedA(*)(DerivedB)){} ok, 回頭去看其中一個型別: typeA(*)(typeB) 不覺得很像 function pointer 嗎? 那麼 typeA(&)(typeB) 又是什麼? 答案是實體 function...(我居然測試測半天才發現這個事實) 請再回到最早的 code, 並在最下面加上這個: Base base; b(base); b(Base()); 得 g++ 錯誤訊息 undefined reference to `b(DerivedB)' undefined reference to `b(DerivedB)' comeau c++... online 版沒有 link, 所以沒有錯誤 :Q ok, 說得亂七八糟,講個結論吧 ...嗯,剛剛本來想舉些例子做結論 不過舉了幾個例子之後又發現一些奇妙的東西 比方說 int value = 5; TypeA a(TypeB(value)); 或 const int value = 5; TypeA a(TypeB(value)); 則 a 是一個 function TypeA a(TypeB(5)); 則 a 是一個 TypeA 物件,用 TypeB::TypeB(int) 建立的暫時物件建立的物件 我被這搞糊塗了... 不過看來假使我這樣寫: int(int) 則這代表型別: int(*)(int) 或 int(&)(int) 我想這也是為什麼 boost::function<int(int)> 可以這樣用了 另外 g++ 有時候也會將 int(int) 視為 int(&)(int) 我想這可能是最佳化機制的緣故…(純猜測) (昏倒, C++ 好謎... 避免使用這種弔詭的用法吧) (畢竟平時應該不會用暫時物件來建立物件吧) (再鑽研下去似乎過於沒意義了) -- By Gamers, For Gamers - from the past Interplay -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.132.128.238 ※ 編輯: godfat 來自: 220.132.128.238 (02/09 04:27)
文章代碼(AID): #13wZte5P (C_and_CPP)
文章代碼(AID): #13wZte5P (C_and_CPP)