创建接受任何子类中的方法的方法



我为这个模糊的问题标题道歉,但我对C++不够熟悉,所以能够更好地表达它。

我试图创建一个方法,将任何子类上的方法作为参数之一,但我遇到了一个编译器错误,我不知道如何修复。我还想给这个类型取个别名,这样就不那么冗长了。我对其他方法持开放态度,但我正在使用的代码或多或少都是这样设置的。

代码:

#include <map>
#include <string>
using std::map;
using std::string;
struct ParentClass;
struct DataClass;
using my_handler_type = uint16_t (ParentClass::*)(DataClass&, DataClass&);
struct ParentClass {
void add_handler(string name, my_handler_type handler) {
handlers.emplace(name, handler);
}
private:
map<string, my_handler_type> handlers;
};
struct ChildClass : ParentClass {

private:
uint16_t some_handling_function(DataClass &, DataClass & );
void setup_handler() {
add_handler( "handler_one", &ChildClass::some_handling_function );
}
};

错误:

example.cpp: In member function ‘void ChildClass::setup_handler()’:
example.cpp:31:37: error: cannot convert ‘uint16_t (ChildClass::*)(DataClass&, DataClass&)’ {aka ‘short unsigned int (ChildClass::*)(DataClass&, DataClass&)’} to ‘my_handler_type’ {aka ‘short unsigned int (ParentClass::*)(DataClass&, DataClass&)’}
31 |         add_handler( "handler_one", &ChildClass::some_handling_function );
|                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|                                     |
|                                     uint16_t (ChildClass::*)(DataClass&, DataClass&) {aka short unsigned int (ChildClass::*)(DataClass&, DataClass&) example.cpp:14:51: note:   initializing argument 2 of ‘void ParentClass::add_handler(std::string, my_handler_type)’
14 |     void add_handler(string name, my_handler_type handler) {
|                                   ~~~~~~~~~~~~~~~~^~~~~~~

您可以将子类成员函数指针强制转换为基类成员函数指针的类型。

static_cast<my_handler_type>(&ChildClass::some_handling_function));

因此:

#include <iostream>
#include <map>
#include <string>
using std::map;
using std::string;
struct ParentClass;
struct DataClass {};
using my_handler_type = uint16_t (ParentClass::*)(DataClass &, DataClass &);
struct ParentClass {
void add_handler(string name, my_handler_type handler) {
handlers.emplace(name, handler);
}
void handle(const std::string &ev) {
if (auto it = handlers.find(ev); it != handlers.end()) {
DataClass d;
(this->*it->second)(d, d);
}
}
private:
map<string, my_handler_type> handlers;
};
struct ChildClass : ParentClass {
uint16_t some_handling_function(DataClass &, DataClass &) {
std::cout << "handling the stuffn";
return 0;
}
public:
void setup_handler() {
// cast the member function pointer here:
add_handler("handler_one", static_cast<my_handler_type>(
&ChildClass::some_handling_function));
}
};
int main() {
ChildClass c;
c.setup_handler();
c.handle("handler_one");
}

演示

问题是指向派生类成员函数的指针无法隐式转换为指向基类成员函数的指针。换句话说,不能将short unsigned int (ChildClass::*)(DataClass&, DataClass&)隐式转换为short unsigned int (ParentClass::*)(DataClass&, DataClass&)

但是,您可以使用static_cast显式地将指向派生类成员函数的指针强制转换为指向基类成员函数的指示器,正如Ted的回答中所做的那样。

最新更新