首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ -基类函数指针调用的替代方法

C++ -基类函数指针调用的替代方法
EN

Stack Overflow用户
提问于 2018-05-06 01:06:31
回答 2查看 479关注 0票数 4

我发现许多帖子都非常清楚地指出,派生类函数不能将分配给基类函数指针。因此,我想知道,如何处理和解决以下情况:

假设我有下面的基本class

代码语言:javascript
复制
class base {
protected:
    typedef void (base::*base_fp)();
    typedef std::map<std::string, base_fp> array;

    array associativeArray;    
};

这个类的主要用途是具有"associative-array of functions“属性。

因此,我希望每个派生的子程序都能够将它们的方法添加到"associativeArray“中。

代码语言:javascript
复制
this->associativeArray["Method"] = &child::method; // from the child class

我使用它的初衷是根据需求调用不同的方法,而不使用条件语句。它应该在一个试图捕捉块来处理一个不存在的索引的情况。既然我原来的方法是不可能的,那么怎样才是正确的方法呢?

编辑:a用例示例

假设关联数组是“算法”functions的数组。然后,对于用户“算法”输入,我应该能够调用在子类中定义的相应方法。

代码语言:javascript
复制
(this->*associativeArray.at("algorithm"))();
EN

回答 2

Stack Overflow用户

发布于 2018-05-06 01:52:26

我最接近您想要的是使用std::function (可从C++11中获得)。首先,为了现代化和使用typedef,我们将更改您的std::function

代码语言:javascript
复制
class base {
protected:
    using base_fp = std::function<void ()>;
    using fn_array = std::map<std::string, base_fp>;
    fn_array fns;

public:
    void call_fn(std::string const &fn_name) {
        auto it = fns.find(fn_name);
        if(it != fns.end()) {
            it->second();
        }
        else {
            // error case
        }
    }
};

因为fn_array存储std::function,所以它可以处理我们可以作为可调用的任何东西。这不能直接与成员函数一起工作(std::invoke可能会起作用,但我还没有使用该库特性),但是您可以使用简单的闭包来获得类似的行为。

代码语言:javascript
复制
class derived : public base {
public:
    derived() {
        fns["foo"] = [this]() { foo(); };
    }

private:
    void foo() {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }
};

您可以使用如下代码来利用这一点:

代码语言:javascript
复制
int main() {
    derived d;
    d.call_fn("foo");
    return 0;
}
票数 4
EN

Stack Overflow用户

发布于 2018-05-06 14:00:52

我猜您需要的是static_cast,因为在具有相同签名的两个函数之间使用是安全的,甚至是从同一个类层次结构生成的。

代码语言:javascript
复制
class base {

   protected:
     typedef void (base::*fn)() ;
     base(){
     fn_arr["foo"]=&base::foo;  
     }  
     void foo()  {
        cout << "i'm foo" << endl;
     }

   public:
     map<std::string, fn> fn_arr;
};

class derived : public base {

   protected:
      void bar() {
          cout <<"i'm bar" << endl;
      }

   public:
      derived() {
          fn_arr["bar"]=static_cast<fn>(&derived::bar);  
      }
};

请参阅此演示

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50195383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档