我有一个包含函数指针列表的类。 这些函数指针指向子类的成员函数,它的绑定方式如下:
functionList.push_back(std::bind(&SubClass::function, this, std::placeholders::_1, std::placeholders::_2));
现在,在使用functionList复制类时,函数指针仍然指向旧类。 如何将函数指针重新绑定到新类?
这是一个示例代码:
#include <vector>
#include <functional>
class SomeClass
{
};
class testClass
{
public:
typedef std::function<void(const SomeClass& var1, const SomeClass& var2)> transitionFunction;
testClass(){}
testClass(const testClass&s)
{
for(transitionFunction func : s.functionList)
{
// how to rebind the function pointer to the new this?
functionList.push_back("???");
}
}
std::vector<transitionFunction> functionList;
};
class SubClass : public testClass
{
SubClass()
{
functionList.push_back(std::bind(&SubClass::function, this, std::placeholders::_1, std::placeholders::_2));
}
void function(const SomeClass& var1, const SomeClass& var2)
{
}
};
谢谢!
答案 0 :(得分:3)
您必须复制您的子类。实际上 - 您只需要在复制构造函数中进行默认初始化:
class SubClass : public testClass
{
...
SubClass(const SubClass&) : SubClass()
{}
...
};
如果您的示例是非常简化的示例,那么您需要拥有自己的function
类rebind
函数。
<强> [UPDATE] 强>
请记住,重新绑定是你的子类的责任 - 所以,我做这样的事情:
您的基类应该只有默认副本(您可能不会指定它 - 默认为默认值):
class testClass
{
public:
...
testClass(const testClass&s) = default;
...
};
下一步是在子类中实现重新绑定:
class SubClass : public testClass
{
public:
using transitionFunctionRebindable =
std::function<void(SubClass*, const SomeClass&, const SomeClass&)>;
struct FunctionWrapper
{
void operator()(const SomeClass& var1, const SomeClass& var2)
{
function(thisObject, var1, var2);
}
SubClass* thisObject;
transitionFunctionRebindable function;
};
transitionFunction rebind(transitionFunction& function)
{
FunctionWrapper* fr = function.target<FunctionWrapper>();
if (fr)
{
return FunctionWrapper{this, fr->function};
}
else
{
// in case your base class added something out of your control
return function;
}
}
施工改变了一点:
SubClass()
{
functionList.push_back(FunctionWrapper{this, std::bind(&SubClass::function, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)});
}
然后,复制你的子类:
SubClass(const SubClass& source) : testClass(source)
{
for (auto& f: functionList)
f = rebind(f);
}
工作demo。