函数指针数组,其中包含不同类的类函数



InSomeClass.h

class SomeClass{
public:
static std::vector<void (*)()> UpdateFuncs;
}

InOtherClass.h

class OtherClass{
private:
void Update();
public:
OtherClass();
}

在其他类中.cpp

OtherClass::OtherClass(){
Time::UpdateFuncs.push_back(&(this->Update));
}

在构建时'&':我对绑定成员函数表达式进行了非法操作 如果我这样做:

.push_back(&Update);

然后我得到"没有重载函数的实例

std::vector<_Ty, _Alloc>::p ush_back [with _Ty=void (*)(), _Alloc=std::allocator]" 匹配参数列表">

提前致谢

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只是安全和现代的方法。

问题

您尝试分配给类型的普通函数指针void(*)()void(OtherClass::*)()类型的成员函数指针。

不幸的是,这两种类型是不兼容的:普通函数只能用其参数调用,成员函数指针只能为特定对象调用。

第一个解决方案:成员函数指针

您必须更改向量的定义以使其使用成员函数指针。

class OtherClass;  // forward deaclaration
class SomeClass {
public:
static std::vector<void (OtherClass::*)()> UpdateFuncs;
};

然后,您可以按预期回推函数:

OtherClass::OtherClass() {
SomeClass::UpdateFuncs.push_back(&OtherClass::Update);
}

在线演示

遗憾的是,您不能将其与指向其他类或普通函数指针的成员函数指针混合使用。 并且您必须指定在调用函数时要使用的对象。

更好的解决方案:命令模式

命令模式比函数指针具有更大的灵活性。 由于命令的专用化,您可以混合调用普通函数指针、不同类的成员函数指针或即席函数的命令。

这些命令可能如下所示:

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));
}

最后,这里有一个完整的在线演示,它调用了为某些本地对象自动注册的两个命令,甚至添加了与任何其他对象无关的第三个临时命令。

最新更新