提问人:DLWHI 提问时间:8/22/2022 更新时间:8/22/2022 访问量:52
让事件不受保护是坏事吗?
Is it bad to leave events unprotected?
问:
我正在编写一些代码,其中包括自定义实现的事件以及使用这些事件并在发生某些事情时调用它们的类(例如窗口关闭)。它看起来像这样:
// phony.h
class Phony
{
public:
Phony();
~Phony();
// some stuff
void i_invoke_click();
void i_invoke_resize();
private:
Event<Arg1> click;
Event<> resize;
Event<Arg2> event3;
Event<Arg3> event4;
};
// event.h
template <typename... Args>
class Event
{
public:
void invoke(Args... params) const
void add(std::function<void(Args...)> func)
void remove(std::function<void(Args...)> func)
void operator+=(std::function<void(Args...)> func) // same as add
void operator-=(std::function<void(Args...)> func) // same as remove
void operator()(Args... params) // invoke
private:
std::list<std::function<void(Args...)>> invoke_list;
};
现在我需要实现一些接口,以便其他类可以订阅/取消订阅单击等事件。我考虑了两种方法:
- 使访问方法像(这将使许多方法变得不方便)
subscribe_to_click(func)
- 或者将事件公开,以便您可以通过 +=(这很方便)直接访问它们
但我认为第二种放置事件的方式违反了封装,但我不确定。所以问题是:是否可以公开事件,或者我应该以丑陋(但安全)的方式进行?
答:
2赞
RoQuOTriX
8/22/2022
#1
来自 C# 背景的我建议是将像 IObservable 这样的基类用于 Events,它通过运算符重载实现某种方法或方法。然后,通过返回引用事件本身的引用,使 IObservables 公开:subscribe
#include <functional>
#include <list>
template <typename... Args>
class IObservable
{
public:
void operator+=(std::function<void(Args...)> func); // same as add
void operator-=(std::function<void(Args...)> func); // same as remove
};
template <typename... Args>
class Event : public IObservable<Args...>
{
public:
void operator()(Args... params); // invoke
private:
std::list<std::function<void(Args...)>> invoke_list;
};
class Phony
{
public:
Phony();
~Phony();
void i_invoke_click();
void i_invoke_resize();
IObservable<int>& Click() { return click; }
IObservable<>& Resize() { return resize; }
IObservable<int>& Event3() { return event3; }
IObservable<int>& Event4() { return event4; }
private:
Event<int> click;
Event<> resize;
Event<int> event3;
Event<int> event4;
};
void foo(int x);
int main()
{
Phony p;
p.Click() += &foo;
// p.Click()(); no invoke possible
}
评论
0赞
DLWHI
8/22/2022
没这么想过,谢谢你的回答。
评论
Phony
Phony