【问题标题】:How do I create an array of method pointers in C++?如何在 C++ 中创建方法指针数组?
【发布时间】:2013-05-28 16:37:36
【问题描述】:

如何在 C++ 中创建方法指针数组?

问题是,尽管这些方法具有相同的签名,但它们属于不同的类。 这些类继承自同一个类。

例如:

class A : public Base {
    virtual bool work();
}

class B : public Base {
    virtual bool work();
}

我需要创建一个指向方法 A::work 和 B::work 的指针数组,在 另一个班级。

编辑 1:

我决定接受 Useless 的建议,选项 1:

vector<Base*> units;
Base *a = new A();
Base *b = new B();
units.push_back(a);
units.push_back(b);

谢谢

【问题讨论】:

  • 你不能只创建一个指向基类成员的指针数组吗? bool (Base::*array)[2]; 之类的东西?
  • bool (*Base::work)() 应该是可行的,只要 work()Base 中定义。
  • 我不得不问:您是否有理由不只是进行虚拟调用而不是尝试在这里使用函数指针?
  • 你确定你问的是你的问题,而不是你想到的解决方案吗?
  • 只有一个'Base'类指针数组。然后你可以在从数组中选择一个随机指针后调用虚拟“工作”函数。

标签: c++


【解决方案1】:

第一个选项:

如果不同的方法只是不同子类中相同虚拟方法的实现,即。 Base 看起来像:

class Base {
public:
    virtual bool work() = 0;
}

那么所有你的方法指针的类型都是bool (Base::*)()。在这种情况下,您的问题是选择一个 object 来调用此方法,因此您可能拥有一个包含不同动态类型的 Base* 指针的容器。


第二个选项:

你的类真的不相关,你只想调用带有签名bool (*)()的函数而不用担心对象。

在这种情况下,要么:

  1. 你的类和它们的实例真的无关紧要,你可以只使用静态方法
    • 所以只需使用免费函数
  2. 需要一个实例,但在选择函数时知道它是什么类型

    • 您需要一个可以捕获实例的函子,并提供兼容的空值调用运算符。正如已经建议的那样,std::function&lt;bool()&gt; 是最简单的方法。例如,您可以像这样填充向量:

      std::vector<std::function<bool()>> fvec() {
          A a;
          B b;
          std::vector<std::function<bool()>> funcs;
          funcs.push_back( [a]() { return a.work(); } );
          funcs.push_back( [b]() { return b.work(); } );
          return funcs;
      }
      

      请注意,ab 对象在 lambda 中按值捕获,因此 AB 是否具有任何类型的继承关系不再重要。

【讨论】:

  • 这是否比下面 Edward A 的方法更好?
  • 它们非常相似。我发现 lambdas 更具可读性,但 Edward 可能相当不同意。此外,正如 Salgar 指出的那样,如果您还没有 C++11,则可以使用与 Edwards 代码等效的 Boost。
  • 顺便说一句,我编辑了我的原始帖子。这就是你的第一个选项的意思吗?
  • 没错,如果 work 是您要调用的唯一函数。
  • 非常感谢,现在不需要 std::bind 或 lambdas。
【解决方案2】:

创建std::function的数组(std::vector)

使用std::function,您可以使用std::bind 来创建指向任何成员函数的函数指针。对于成员函数,您还必须绑定到对象的特定实例。

这是一个如何使用它的示例。 std::function to member function

如果您没有 c++11 访问权限,您可以对 boost::bindboost::function 执行相同操作

【讨论】:

    【解决方案3】:

    您可以使用std::functionstd::bind 的组合,这两者都可以在&lt;functional&gt; 中找到。

    例子:

    #include <functional>
    #include <vector>
    
    class Base
    {
    public:
        virtual bool work() = 0;
    };
    
    class A : public Base
    {
    public:
        bool work() {return true;}
    };
    
    class B : public Base
    {
    public:
        bool work() {return false;}
    };
    
    int main()
    {
        std::vector<std::function<bool(void)>> list;
    
        A t1;
        B t2;
    
        list.push_back(std::bind(&A::work, t1));
        list.push_back(std::bind(&B::work, t2));
    
        for (auto& i : list)
        {
            printf("%s\n", (i()) ? "true" : "false");
        }
    }
    

    输出:

    true
    false
    

    【讨论】:

    • 你认为这比上面Useless的方法更好吗?
    • @user2381422 正如 Useless 所说,它们非常相似,但是我没有看到使用调用函数的 lambda 的意义,它增加了间接级别,老实说,我找到了 @987654329 @ 选项清洁器,这就是我要使用的。此外,使用bind + function 意味着您可以使用所有三个选项,lambdas、指针、引用。
    【解决方案4】:

    好吧,从技术上讲,您可以创建一个指向成员函数的指针数组,尽管正如其他人建议的那样,您可能不应该这样做。这有效:

    class Base {
        public:
        bool work()
        {
            return true;
        }
    };
    
    int main()
    {
        bool (Base::*arr[2])() = { &Base::work, &Base::work };
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      • 2020-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多