我已经就此事做了一些研究,但还没有找到具体的解决方案.我真的希望能够做到这一点:
public delegate void VoidFloatCallback(float elapsedTime);
public VoidFloatCallback OnEveryUpdate;
public VoidFloatCallback OnNextUpdate;
public virtual void Update(GameTime gameTime)
{
if (OnNextUpdate != null)
{
OnNextUpdate(gameTime);
OnNextUpdate = null;
}
if (OnEveryUpdate != null)
{
OnEveryUpdate(gameTime);
}
this.OnUpdate(gameTime);
}
Run Code Online (Sandbox Code Playgroud)
但是在C++当然.我发现只有一种解决方案可以为我提供这样的功能; 但此后一直处于脱机状态,但我将其转发到http://codepad.org/WIVvFHv0.我发现解决方案的唯一问题是它不是现代的C++ 11代码,缺乏lambda支持.
我知道我可以用
std::function
Run Code Online (Sandbox Code Playgroud)
但是,唯一的问题是它不支持的运营商" ,".现在我已经考虑过创建自己的Events类并拥有一个+=-===
vector<std::function>
Run Code Online (Sandbox Code Playgroud)
有一些模板,但我发现std :: function没有实现运算符,==所以我不能让它看起来像C#那样.
无论如何,我的问题是:
我想知道如何使用C++ 11实现这样的事件系统 - 或者甚至是可能的.或者即使您知道一种更好/正确的方法来实现支持多个侦听器的回调(我想尽可能避免完整的Observer模式实现.)
更新#1
我对运营商的意图是这样的:
void some_func(float f) { /** do something with f **/ }
void some_other_func(float f) { /** do something else with f **/ }
OnNextUpdate += some_func();
OnNextUpdate += some_other_func();
OnNextUpdate(5.0f);
// both some_func() and some_other_func() are called
OnNextUpdate -= some_other_func();
OnNextUpdate(5.0f);
// only some_func() is called
Run Code Online (Sandbox Code Playgroud)
Die*_*ühl 16
C++函数对象机制与C#方法完全不同.特别是,函数对象基于值而不是引用.在C++中删除函数对象时,可以识别函数对象的原因是函数对象具有一个标识,即它们被调用的对象和被调用的成员函数.此外,在C++中,不可能一次直接获取对象和成员函数的地址.
为了使代理系统能够移除功能,您可以创建类似std::function<Signature>但使用多个功能的东西,并要求每个使用的功能都是EqualityComparable.下面是这种委托系统的简单实现,以及成员函数的绑定器如何看起来的示例实现.有许多明显的扩展机会,因为此实现仅用作演示.
#include <algorithm>
#include <iostream>
#include <memory>
#include <utility>
#include <vector>
template <typename Signature>
struct delegate;
template <typename... Args>
struct delegate<void(Args...)>
{
struct base {
virtual ~base() {}
virtual bool do_cmp(base* other) = 0;
virtual void do_call(Args... args) = 0;
};
template <typename T>
struct call: base {
T d_callback;
template <typename S>
call(S&& callback): d_callback(std::forward<S>(callback)) {}
bool do_cmp(base* other) {
call<T>* tmp = dynamic_cast<call<T>*>(other);
return tmp && this->d_callback == tmp->d_callback;
}
void do_call(Args... args) {
return this->d_callback(std::forward<Args>(args)...);
}
};
std::vector<std::unique_ptr<base>> d_callbacks;
delegate(delegate const&) = delete;
void operator=(delegate const&) = delete;
public:
delegate() {}
template <typename T>
delegate& operator+= (T&& callback) {
this->d_callbacks.emplace_back(new call<T>(std::forward<T>(callback)));
return *this;
}
template <typename T>
delegate& operator-= (T&& callback) {
call<T> tmp(std::forward<T>(callback));
auto it = std::remove_if(this->d_callbacks.begin(),
this->d_callbacks.end(),
[&](std::unique_ptr<base>& other) {
return tmp.do_cmp(other.get());
});
this->d_callbacks.erase(it, this->d_callbacks.end());
return *this;
}
void operator()(Args... args) {
for (auto& callback: this->d_callbacks) {
callback->do_call(args...);
}
}
};
// ----------------------------------------------------------------------------
template <typename RC, typename Class, typename... Args>
class member_call {
Class* d_object;
RC (Class::*d_member)(Args...);
public:
member_call(Class* object, RC (Class::*member)(Args...))
: d_object(object)
, d_member(member) {
}
RC operator()(Args... args) {
return (this->d_object->*this->d_member)(std::forward<Args>(args)...);
}
bool operator== (member_call const& other) const {
return this->d_object == other.d_object
&& this->d_member == other.d_member;
}
bool operator!= (member_call const& other) const {
return !(*this == other);
}
};
template <typename RC, typename Class, typename... Args>
member_call<RC, Class, Args...> mem_call(Class& object,
RC (Class::*member)(Args...)) {
return member_call<RC, Class, Args...>(&object, member);
}
// ----------------------------------------------------------------------------
void f(char const* str) { std::cout << "f(" << str << ")\n"; }
void g(char const* str) { std::cout << "g(" << str << ")\n"; }
void h(char const* str) { std::cout << "h(" << str << ")\n"; }
// ----------------------------------------------------------------------------
struct foo
{
int d_id;
explicit foo(int id): d_id(id) {}
void bar(char const* str) {
std::cout << "foo(" << this->d_id << ")::bar(" << str << ")\n";
}
void cbs(char const* str) {
std::cout << "foo(" << this->d_id << ")::cbs(" << str << ")\n";
}
};
// ----------------------------------------------------------------------------
int main()
{
delegate<void(char const*)> d0;
foo f0(0);
foo f1(1);
d0 += f;
d0 += g;
d0 += g;
d0 += h;
d0 += mem_call(f0, &foo::bar);
d0 += mem_call(f0, &foo::cbs);
d0 += mem_call(f1, &foo::bar);
d0 += mem_call(f1, &foo::cbs);
d0("first call");
d0 -= g;
d0 -= mem_call(f0, &foo::cbs);
d0 -= mem_call(f1, &foo::bar);
d0("second call");
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4747 次 |
| 最近记录: |