在 SomeClass.h
中class SomeClass{
public:
static std::vector<void (*)()> UpdateFuncs;
}
在 OtherClass.h
中class OtherClass{
private:
void Update();
public:
OtherClass();
}
在 OtherClass.cpp
中OtherClass::OtherClass(){
Time::UpdateFuncs.push_back(&(this->Update));
}
On Build我对绑定成员函数表达式进行'&':
非法操作
如果我这样做:
.push_back(&Update);
然后我得到“没有重载函数的实例
std :: vector&lt; _Ty,_Alloc&gt; :: push_back [with _Ty = void(*)(),_ Alloc = std :: allocator]“匹配参数列表”
提前感谢
答案 0 :(得分:1)
OtherClass::Update
不适合void (*)()
函数指针,因为它是非静态成员函数;就好像它有一个“不可见的”OtherClass*
参数。
使用std::function
来实现目标:
#include <functional>
class Time
{
public:
static std::vector<std::function<void()>> UpdateFuncs;
};
在OtherClass.cpp中,使用this
- 捕获lamba作为函数对象:
OtherClass::OtherClass()
{
Time::UpdateFuncs.push_back([this] { Update(); });
}
当然,如果您将Update
设为静态,那么您仍然可以使用void (*)()
,因为“隐身”参数已删除,但std::function
只是安全而现代的方式。
答案 1 :(得分:0)
您尝试为void(*)()
类型的普通函数指针指定类型为void(OtherClass::*)()
的成员函数指针。
不幸的是,这两种类型是不兼容的:只能使用其参数调用普通函数,并且只能为特定对象调用成员函数指针。
您必须更改向量的定义以使其使用成员函数指针。
class OtherClass; // forward deaclaration
class SomeClass {
public:
static std::vector<void (OtherClass::*)()> UpdateFuncs;
};
然后你可以按预期推回函数:
OtherClass::OtherClass() {
SomeClass::UpdateFuncs.push_back(&OtherClass::Update);
}
不幸的是,你不能将它与成员函数指针混合到其他类或普通函数指针。并且您必须在调用函数时指定要使用的对象。
command pattern 可让您比功能指针更灵活。由于命令的专业化,您可以混合将调用普通函数指针,不同类的成员函数指针或ad-hoc函数的命令。
命令可能如下所示:
class Command {
public:
virtual void execute() = 0;
virtual ~Command();
};
class CommandOtherClass : public Command {
OtherClass *target;
void (OtherClass::*f)();
public:
CommandOtherClass (void (OtherClass::*fct)(), OtherClass*t);
void execute() override;
};
实施非常简单:
CommandOtherClass::CommandOtherClass (void (OtherClass::*fct)(), OtherClass*t)
: f(fct),target(t)
{
}
void CommandOtherClass::execute() {
(target->*f)();
}
SomeClass函数可以更改如下:
class SomeClass {
public:
static std::vector<unique_ptr<Command>> UpdateFuncs;
static void executeAll();
};
请注意,您可以开发它以包含注册和取消注册功能,这样您也可以从涉及不再存在的对象的矢量命令中删除它。
向矢量添加新命令将如下所示:
OtherClass::OtherClass() {
SomeClass::UpdateFuncs.push_back(make_unique<CommandOtherClass>(&OtherClass::Update, this));
}
最后,这里有一个完整的 online demo ,可以调用为某些本地对象自动注册的两个命令,甚至可以添加与任何其他对象无关的第三个ad hoc命令。