[問題] 什麼時後 不該用/該用reference當member

作者: lovejomi (JOMI)   2018-07-23 19:16:39
寫一個建構子
Foo(ICallback* callback)
: mCallback(callback){ assert(mCallback); }
被問說那為什麼你mCallback不用reference 然後Foo就開成(ICallback&)就好
我不想這樣改
但我沒有強力的說法比較出哪一種比較好或是合理
我的看法
用ref, caller勢必要*ptr 做dereference才能傳進來
雖然說reference 可以當作non null去操作
但有心要傳*null也不是不行.
開reference 給別人傳,比起pointer更有機會caller不小心傳入local variable
以上都可以用一句話“哪有人會這樣寫”來否定用pointer存.
而用reference 可以給人一種 必定要想辦法生出一個物件才能呼叫的感覺...
實在想不到哪個時候 用reference
才是合理的寫法.
反而我自己是很少看過member 用reference去存...
不知道大家在design上會有什麼考量
謝謝
作者: sarafciel (Cattuz)   2018-07-23 19:47:00
我覺得你把物件變數的記憶體控管交出去就開始錯了要嘛寫member function把生member variable的部分封裝起來給使用者call 要嘛丟進來的東西你自己再new一塊做copy
作者: AstralBrain   2018-07-23 20:21:00
我覺得smart pointer唯一解
作者: BlazarArc (Midnight Sun)   2018-07-23 20:26:00
沒有說明Foo跟ICallBack的生命週期跟擁有權沒辦法回答你的看法那段的理由我覺得還蠻弱的 我會預設用ref不用ref的理由, class需要被copy
作者: lovejomi (JOMI)   2018-07-23 20:32:00
生命周期都比這class本身久, 我知道理由很弱,但我很難描述我不想用ref的理由,總覺得不夠彈性
作者: sarafciel (Cattuz)   2018-07-23 22:15:00
阿對還有smart pointer這個解 我老了QQ
作者: nobodycares (沒人在乎)   2018-07-23 22:40:00
std::function 選我正解好嗎
作者: Killercat (殺人貓™)   2018-07-23 23:35:00
你要考慮callback生命週期 用reference傳入的話其實有很高的機率會發生人為錯誤pointer除非耍蠢 很不自然的傳一個local variable的pointer進來 不然基本上不太會出包 但ref機率高得多另外 smart pointer是通用解沒錯...
作者: eye5002003 (下一夜)   2018-07-24 00:44:00
我的習慣是如果會改變外部狀態就用指標,使用但是不會去改變外部就用ref(常常搭配const來保證不會修改)還需要擔心生命週期的情況就都用std::shared_ptr處理
作者: ketrobo (貓蘿蔔)   2018-07-24 02:23:00
ref比較好,B(A&),如果正確依照物件生命週期設計,乾淨的程式結構會是B先結束,之後才是A結束,用pointer會變成語法上少了限制,隨便寫都會產生cyclic dependency的問題,造成物件生命週期結束這塊非常難寫,然後系統資源沒釋放完,浪費工程師的生命在找問題,最後跟你說解決的辦法是定期reset整臺機器…簡單講B(A&)很自然就從語法上讓你設計出遵循著RAII的程式結構
作者: tinlans ( )   2018-07-24 05:47:00
從語法層級探討很沒意義,高興怎樣就怎樣啊,真非要用reference 還有 reference_wrapper 可以活用。正確來講還是要從生命週期去探討,用更高階抽象的概念來說就是 aggregation 跟 composition 的差異。如果對這兩個名詞陌生,可能要去補足一下 OOAD 的知識。身為一名工程師,設計圖之類的當然要會畫,然後按圖施工,今天會有這種問題跑出來就是因為你沒圖。
作者: andyjy12 (??)   2018-07-28 12:57:00
reference 不能直接更換綁定對象

Links booklink

Contact Us: admin [ a t ] ucptt.com