【发布时间】:2009-08-16 12:55:42
【问题描述】:
以下回调类是“可调用事物”的通用包装器。我真的很喜欢它的 API,它没有模板而且非常干净,但在底层有一些我无法避免的动态分配。
有什么办法可以去掉下面代码中的new和delete,同时保持回调类的语义和API?我真希望我能。
需要的东西:
// base class for something we can "call"
class callable {
public:
virtual void operator()() = 0;
virtual ~callable() {}
};
// wraps pointer-to-members
template<class C>
class callable_from_object : public callable {
public:
callable_from_object(C& object, void (C::*method)())
: o(object), m(method) {}
void operator()() {
(&o ->* m) ();
}
private:
C& o;
void (C::*m)();
};
// wraps pointer-to-functions or pointer-to-static-members
class callable_from_function : public callable {
public:
callable_from_function(void (*function)())
: f(function) {}
void operator()() {
f();
};
private:
void (*f)();
};
回调类:
// generic wrapper for any callable
// this is the only class which is exposed to the user
class callback : public callable {
public:
template<class C>
callback(C& object, void (C::*method)())
: c(*new callable_from_object<C>(object, method)) {}
explicit callback(void (*function)())
: c(*new callable_from_function(function)) {}
void operator()() {
c();
}
~callback() {
std::cout << "dtor\n"; // check for mem leak
delete &c;
}
private:
callable& c;
};
API 示例:
struct X {
void y() { std::cout << "y\n"; }
static void z() { std::cout << "z\n"; }
} x;
void w() { std::cout << "w\n"; }
int main(int, char*[]) {
callback c1(x, &X::y);
callback c2(X::z);
callback c3(w);
c1();
c2();
c3();
return 0;
}
非常感谢!! :-)
【问题讨论】:
-
很抱歉,它仍然使用模板。模板有什么问题?
-
它在内部使用模板,但在“main”中查看 API。没有模板。一般来说,模板没有什么问题,我只是觉得它们不需要实现回调。以回调 c1 为例,我不需要说 callback
等... -
另外,不是回调的类型不应该依赖于被调用的东西。 callback 的类型与 callback 的类型不同吗?概念上不是。这些是 CALLBACKS,不管它调用 A 还是 B 中的东西!
-
你只是在重新实现
boost::function。改用那个。如果你想知道怎么做,请阅读它的代码。这是一段由顶级 C++ 程序员编写的代码。 :) -
你能回答使用 boost::function 来实现我想要的 API 吗?
标签: c++ templates memory-management callback pointer-to-member