如何通过接口存储成员函数指针

How to store a member function pointer through an interface

本文关键字:函数 指针 成员 存储 何通过 接口      更新时间:2023-10-16

我会创建这样的接口:

class IMother {
public:
  // This getter return a map which contains a member functer pointer
  virtual map<string, void (IMother::*)()> getMap() const = 0;
  virtual ~IModule() {};
};

然后,创建一个子项并覆盖getter,以便返回一个仅包含child_1成员函数指针的映射

class Child_1 : public IMother {
private:
  map<string, void (Child1::*)(int)> _map;
public:
  void do_something_1(int a) {
     // Something...
  }
  void do_something_2(int a) {
   // Something...
  }
  virtual map<string, void (Child1::*)(int)> getMap() {
     _map["do_1"] = &do_something_1;
     _map["do_2"] = &do_something_2;
     return _map;
  }

我想我能让它发挥作用,因为在我看来,我认为Child1是一个IMother,所以我有权写它,但我不能。。

int main() {
   IMother *mother = new Child_1;
   // I don't know how run a method through a map
   mother->getMap["do_1"](42); // Not seem to work
   return 0;
}

有没有一种方法可以通过接口存储成员函数指针?

这里有几个问题:

  1. 首次向成员分配指针不正确:

    此:

    _map["do_1"] = &do_something_1;
    _map["do_2"] = &do_something_2;
    

    应为:

    _map["do_1"] = &Child1::do_something_1;
    _map["do_2"] = &Child1::do_something_2;
    
  2. 其次,getMap()在IMother和Child1上的返回类型不同,因为一个不带params和指向IMother成员的指针,另一个带int和指向Child1成员的指针。这两个差异导致C++中的返回类型不同。

    IM其他:

    map<string, void (IMother::*)()>  
    

    Child1:

    map<string, void (Child1::*)(int)>
    

    由于返回类型不同,Child1没有覆盖IMother中定义的所有纯虚拟函数,因此您无法实例化Child1的实例。

  3. 第三,您的成员函数调用不正确。成员函数仍然需要在调用之前提供"成员"。例如

    class SomeClass;
    typedef void (SomeClass::* SomeClassFunction)(void);
    void Invoke(SomeClass *pClass, SomeClassFunction funcptr) {
        (pClass->*funcptr)(); 
    };
    

话虽如此,我还是会看看stl的功能性标题。stl函数库将允许您编写以下内容,并在以后以比内置C++语法简单得多的语法调用它们:

typedef std::function<float (float)> MyFuncType;
map<sting, MyFuncType> myFuncs;
myFuncs["myCustomSin"] = &SomeClass::SomeCustomSinFunc;
myFuncs["cSin"] = &sin;

IMother::getMapIChild::getMap具有不同的返回类型。只有当这些返回类型是协变的时,才允许这样做。尽管IMotherIChild是协变的,但std::map<...IMother...>std::map<...IChild..>不是。因此,您的示例无法编译为错误:invalid covariant return type