作者boy770329 (A-So)
看板C_and_CPP
標題Re: [問題] 什麼時後 不該用/該用reference當member
時間Sun Jul 29 04:24:30 2018
看到為什麼不用std::function剛好我也有這個問題
如果function長這樣foo(ICallback &)或foo(ICallback *)
那一個繼承ICallback的物件可以在自己的scope內呼叫foo(*this)或foo(this)
假設今天AddCallback是物件CPublisher開給外面註冊callback function
該物件提供另外一個移除callback的RemoveCallback
對於一個需要聽該事件的物件CSubscriber有個很簡單的作法如下
class CSubscriber : private ICallback
{
public:
CSubscriber(const CPublisher& aPub) : mPub(aPub)
{ mPub.AddCallback(*this); }
~CSubscriber() {mPub.RemoveCallback(*this); }
...
private:
const CPublisher& mPub;
}
這個情況下如果把ICallback換成std::function, 的確可以用std::bind搭配this跟某個
member function一樣呼叫AddCallback, 但是Remove怎麼辦? 再bind一次?
原先的做法, 物件CPublisher如果需要存多個Callback, 不管用reference還是pointer都
可以利用記憶體位置唯一的特色把傳進來的東西的記憶體位置存在某種container內
所以對CSubscriber生成的Object, this在建構跟解構式會是一樣的值
但是如果改用std::function跟bind, 原本很方便的這個作法似乎就不能用了
(有跟同事討論過實作AddCallback return ID存下來, Remove傳ID判斷但覺得實作太麻煩)
這是我唯一想到會傾向用reference/pointer而不用std::function的情況
至於原本的問題大概就像前面的人回答的,
pointer可以是nullptr, 所以你做一個set既可以設值也可以傳nullptr做unset
reference就基本上強迫傳存在的東西了, 不考慮local反正用pointer也避免不了外面delete
觀念不見得都對 有錯請幫訂正 謝謝
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 213.127.105.210
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1532809476.A.087.html
推 soheadsome: 簡單說 感覺你想做c#的delegate 07/29 08:12
推 KanzakiHAria: 你會無法用是因為一開始就是用c style而非OO的概念 07/29 08:16
想不太到用OO的概念要怎麼好做Add跟Remove callback的實作...記憶體位置太方便
推 soheadsome: 而且你的型態跟callback在compile time都決定好了 沒 07/29 08:23
→ soheadsome: 辦法用std::visit解決? 07/29 08:23
std::visit太新了還沒研究過...
推 lovejomi: 題外話,為什麼Icallback會想用private繼承? 有什麼好 07/29 08:51
→ lovejomi: 處嗎這裡 07/29 08:51
Effective C++某章的內容,雖然語意上用public才是對的,但是用private可以避免使用者
直接建立這個物件然後可以呼叫他的ICallback成員函式
推 lovejomi: 另外你是問說要是addcallback不是吃Icallback而是收std 07/29 08:58
→ lovejomi: function 該怎麼做到remove callback嗎 07/29 08:58
對因為用ICallback的傳統寫法this是唯一的, 但是bind出來的std::function照我的理解
出來的值不會是唯一
推 soheadsome: std::optional加上std:: function做不到? 07/29 11:32
不太懂這個意思, 只是取代pointer版Add應該可以, 但是取代我的例子Remove應該不行
※ 編輯: boy770329 (213.127.105.210), 07/29/2018 15:43:50