我正在尝试在c ++中创建某种事件处理程序。所以我得到了以下内容:
template<class W>
delegate<W>* bind(W* obj, void (W::*f)(char*))
{
return new delegate<W>(obj,f);
}
委托类和此函数完美运行。问题是如何存储与bind函数返回的委托对象?我知道使用boost和c ++ 11这很容易但是如何在不使用它的情况下解决这个问题?我确信它必须是可能的,因为在诸如boost和c ++ 11这些复杂的东西之前它是可能的。
(并且他们也以某种方式在提升中做到了。)
所以我想做的事情:
class Test1
{
Test1(){}
~Test1(){}
template<class W>
bind(W* obj, void (W::*f)(char*))
{
myCallBack = new delegate<W>(obj,f);
}
private:
delegate * myCallBack; //this does not work because I have to define the template but I dont know it know it could be anything
}
class Test2
{
Test2()
{
Test1 t;
t.bind(this, &Test2::callit);
}
~Test2(){}
void callit(char*)
{
}
}
答案 0 :(得分:3)
好的,我明白你到底需要什么。您只需要一个简单的回调运算符,具有固定的调用签名。
此示例演示了如何针对您的特定情况执行此操作:
#include <iostream>
#include <utility>
#include <type_traits>
#include <vector>
#include <algorithm>
struct Cb {
virtual ~Cb(){}
virtual void call(const char*) = 0;
};
template<class C>
struct CmCb : Cb {
CmCb( C& c_, void (C::*fn_)(const char*) ) : c(c_),fn(fn_)
{
}
virtual void call(const char* s) {
(c.*fn)(s);
}
C& c;
void (C::*fn)(const char*);
};
struct A {
void foo( const char* s ) {
std::cout<<s<<std::endl;
}
};
class Test1
{
public:
Test1(){}
~Test1(){delete cb;}
template<class W>
void bind(W* obj, void (W::*f)(const char*))
{
cb=new CmCb<W>(*obj,f);
}
void callit(const char* s ){
cb->call(s);
}
private:
Cb* cb;
};
int main()
{
Test1 t;
A a;
t.bind(&a, &A::foo );
t.callit("hey");
}
如果您需要更复杂的解决方案(通用签名),那么您可以使用boost::any进行某种类型的擦除。
答案 1 :(得分:0)
智能指针确实比原始标准(std::auto_ptr
)提供的更复杂。但它们都涉及更复杂的概念(主要是关于共享指针的引用计数)。使用这些产品有什么阻碍?
如果您需要为c++03环境提供更轻量级的智能指针实现,Andrei Alexandrescu的Loki Library可能对您有用。我已经成功地将它无缝集成到有限的系统环境中(比使用boost更好更容易)。
甚至不要试图完全靠自己做,有很多陷阱...... 如果您能够启用c++11标准,请使用这些标准!