【发布时间】:2017-11-07 20:40:21
【问题描述】:
TL;DR 如何让Base::Choose 接受Derived::CustomUserFunction 作为参数?
我得到的错误,我明白为什么我得到它,但我不知道如何解决它:
Argument of type "Derived::* (...)" is incompatible with parameter of type "Base::* (...)"
#include <iostream>
class Base {
public:
void Base::Choose(void(Base::*FctPtr)()) {
(this->*FctPtr)();
}
virtual void Base::CustomUserFunction() = 0;
};
class Derived : public Base {
public:
virtual void Derived::CustomUserFunction() {
std::cout << "CustomFunction\n";
}
};
int main() {
Derived D;
D.Choose(&D.CustomUserFunction);
}
完整版
我正在编写一个使用自定义用户函数的离散事件模拟引擎 (DESEngine)。由于这些自定义用户函数是特定于问题的,我希望能够在不知道其签名名称的情况下调用它们。引擎在文本文件中读取TURN_ON 并查找映射到 unordered_map 中 TURN_ON 字符串别名的函数指针。
基本上 DESEngine 会调用 UserEvents::Choose(std::string Name),它会调用由它的事件名称(字符串)给出的函数。
一切都运行良好,但可管理性变得越来越困难,因为我必须使用引擎解决许多不同的问题(从微分方程求解到模拟简单计算机)。 (而且我的 UserEvents 类中有各种不同的特定于问题的函数)
因此,我决定将我的类 UserEvents 设为一个抽象类并为我遇到的各种问题继承它,因此,自定义用户函数将存储在派生类中,不在基类中,但我希望"Choose" 方法驻留在基类中。 如何从基类调用派生类中的函数?
我得到的错误是,我明白为什么会得到它,但我不知道如何解决它:
Argument of type "UserEvents_MVN::* (...)" is incompatible with parameter of type "UserEvents::* (...)"
class UserEvents
{
public:
// Receives an event name and parameters
struct EventWithParams { std::string Name; std::vector<boost::any> Params; };
// Lets an outside class (DESEngine) configure which event to run before calling UserEvents::Choose()
// TODO: Make getters/setters so Events can be passed through a better way
EventWithParams Event;
// Select which function(parameters) to call based on the EventWithParams Event (above)
int UserEvents::Choose();
protected:
void UserEvents::UserFunctionPointerMap_AddFunction
(std::string Alias, void(UserEvents::*FunctionPointer)(const std::vector<boost::any>&));
virtual void UserEvents::BuildUFPAliasMap() = 0;
private:
// Here we have an unordered map that assigns User Function (pointer) to each Key (string or Alias or Event Name)
std::unordered_map<std::string, void(UserEvents::*)(const std::vector<boost::any>&)> UserFunctionPointerAliasMap;
};
下面是Choose的实现
int UserEvents::Choose()
{
try
{
(this->*UserFunctionPointerAliasMap.at(Event.Name))(Event.Params);
return 0;
}
catch (const std::out_of_range e)
{
throw std::exception::exception("Unknown User Event");
return -1;
}
}
派生类示例
#pragma once
#include "..\\UserEvents.h"
class UserEvents_MVN : public UserEvents
{
public:
UserEvents_MVN();
~UserEvents_MVN();
protected:
void UserEvents_MVN::MEMDUMP_LOAD(const std::vector<boost::any> &Parameters);
void UserEvents_MVN::MEMDUMP(const std::vector<boost::any> &Parameters);
void UserEvents_MVN::InstructionDecode(const std::vector<boost::any> &Parameters);
private:
virtual void UserEvents_MVN::BuildUFPAliasMap();
};
以及我如何建立函数指针的索引(UserFunctionPointerAliasMap)
void UserEvents_MVN::BuildUFPAliasMap()
{
UserFunctionPointerMap_AddFunction("MEMDUMP_LOAD", &UserEvents_MVN::MEMDUMP_LOAD );
UserFunctionPointerMap_AddFunction("MEMDUMP", &UserEvents_MVN::MEMDUMP );
UserFunctionPointerMap_AddFunction("DECODE", &UserEvents_MVN::InstructionDecode);
}
【问题讨论】:
-
什么?您正在尝试将指针存储为指向
UserEvents成员的指针,但这些函数不是该类的成员。 -
@BoPersson 你是对的。我希望基类处理存储函数指针的 unordered_map,但我希望它们是其派生类的函数。我该如何解决这个问题?
-
很高兴知道为什么它被否决,这样我下次可以做得更好:)
标签: c++ abstract-class member-function-pointers virtual-inheritance incompatibletypeerror