我已经使用interface ..
实现了我的回调struct ICallback
{
virtual bool operator()() const = 0;
};
和添加回调的功能
void addCallback(const ICallback* callback) { .... }
并使用,回调在某个类中
class BusImplemantation{
public:
struct Foo : ICallback
{
virtual bool operator()() const { return true;}
}foo;
void OtherMethod();
int OtherMember;
};
但是因为回调是类(不是函数/方法),所以我无法在回调访问OtherMethod和OtherMember。如果回调不是类,但只有方法可能。(内部类与方法)
我无法将OtherMethod和OtherMember作为参数传递给回调。
有没有更好的解决方案呢?也许有模板?
答案 0 :(得分:2)
使用std::function
:
void addCallback(const std::function<bool()>) { .... }
class BusImplemantation{
public:
bool Callback() { return true; }
void OtherMethod();
int OtherMember;
};
BusImplemantation obj;
addCallback(std::bind(&BusImplemantation::Callback, obj));
答案 1 :(得分:1)
查看boost::bind了解如何实现此目的的一系列备选方案。
答案 2 :(得分:1)
你可以这样做吗:
typedef std::function<bool()> CallbackFunc;
void addCallback(const CallbackFunc callback) { .... }
class BusImplemantation{
public:
struct Foo
{
Foo(member) : OtherMember(member) { }
bool operator()() const { return true; }
void OtherMethod();
int OtherMember;
}foo;
};
不要让你的回调成为一个接口,而是让它使用std :: function使它成为一个函数对象(一个Functor),而你的仿函数需要的任何额外数据或方法都可以成为仿函数类的一部分。
答案 3 :(得分:1)
使用回调对象而不是自由函数的全部意义在于您可以将任意状态与它们相关联:
class BusImplemantation{
public:
struct Foo : ICallback
{
explicit Foo(BusImplementation &p) : parent(p) {}
virtual bool operator()() const;
private:
BusImplementation &parent;
} foo;
BusImplementation() : foo(*this)
{
addCallback(&foo)
}
void OtherMethod();
int OtherMember;
};
bool BusImplementation::Foo::operator() () const
{
if (parent.OtherMember == 0) {
parent.OtherMethod();
return false;
}
return true;
}
答案 4 :(得分:0)
我认为你的ICallback
接口必须有指向带有基接口的受控类的指针,假设它BusImplemantation
并且内部回调使用这个指针。
struct ICallback
{
virtual bool operator()() const = 0;
void setControlObject(BusImplemantation* o)
{
obj = o;
}
BusImplemantation* obj;
};
class BusImplemantation
{
public:
void addCallback(const ICallback* callback)
{
callback->setControlObject(this);
}
void OtherMethod();
int OtherMember;
};
并使用:
class SomeCb : ICallback
{
bool operator()
{
obj->OtherMethod();
return true;
}
}