作者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://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1532809476.A.087.html
1F:推 soheadsome: 简单说 感觉你想做c#的delegate 07/29 08:12
2F:推 KanzakiHAria: 你会无法用是因为一开始就是用c style而非OO的概念 07/29 08:16
想不太到用OO的概念要怎麽好做Add跟Remove callback的实作...记忆体位置太方便
3F:推 soheadsome: 而且你的型态跟callback在compile time都决定好了 没 07/29 08:23
4F:→ soheadsome: 办法用std::visit解决? 07/29 08:23
std::visit太新了还没研究过...
5F:推 lovejomi: 题外话,为什麽Icallback会想用private继承? 有什麽好 07/29 08:51
6F:→ lovejomi: 处吗这里 07/29 08:51
Effective C++某章的内容,虽然语意上用public才是对的,但是用private可以避免使用者
直接建立这个物件然後可以呼叫他的ICallback成员函式
7F:推 lovejomi: 另外你是问说要是addcallback不是吃Icallback而是收std 07/29 08:58
8F:→ lovejomi: function 该怎麽做到remove callback吗 07/29 08:58
对因为用ICallback的传统写法this是唯一的, 但是bind出来的std::function照我的理解
出来的值不会是唯一
9F:推 soheadsome: std::optional加上std:: function做不到? 07/29 11:32
不太懂这个意思, 只是取代pointer版Add应该可以, 但是取代我的例子Remove应该不行
※ 编辑: boy770329 (213.127.105.210), 07/29/2018 15:43:50