1

如何在 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);

谢谢

4

4 回答 4

5

第一个选项:

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

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

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


第二种选择:

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

在这种情况下,要么:

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

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

      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;
      }
      

      请注意,aandb对象是通过 lambda 中的值捕获的A,因此是否B具有任何类型的继承关系不再重要。

于 2013-05-28T16:55:05.183 回答
4

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

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

这是一个如何使用它的示例。 std::function 到成员函数

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

于 2013-05-28T16:42:58.170 回答
2

您可以使用 中的std::functionstd::bind两者的组合<functional>

例子:

#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
于 2013-05-28T16:45:01.157 回答
1

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

class Base {
    public:
    bool work()
    {
        return true;
    }
};

int main()
{
    bool (Base::*arr[2])() = { &Base::work, &Base::work };
    return 0;
}
于 2013-05-28T16:53:45.420 回答