简体   繁体   English

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

[英]How do I create an array of method pointers in C++?

How do I create an array of method pointers in C++? 如何在C ++中创建方法指针数组?

The problem is, although these methods have the same signature, they are in different classes. 问题是,尽管这些方法具有相同的签名,但它们位于不同的类中。 Those classes inherit from one same class. 这些类继承自同一类。

For example: 例如:

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

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

And I need to create an array of pointers to the methods A::work and B::work, in another class. 我需要在另一个类中创建一个指向方法A :: work和B :: work的指针数组。

Edit 1: 编辑1:

I decided to go with Useless's suggestion, option 1: 我决定接受Useless的建议,选择1:

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

Thanks 谢谢

create an array (std::vector) of std::function 创建一个std :: function的数组(std :: vector)

With std::function you can use std::bind to make a function pointer to any member function. 使用std::function您可以使用std :: bind使函数指针指向任何成员函数。 For member functions you have to also bind to a specific instance of the object. 对于成员函数,还必须绑定到对象的特定实例。

Here is an example of how to use it. 这是一个如何使用它的例子。 std::function to member function std :: function到成员函数

If you do not have c++11 access, you can do the same with boost::bind and boost::function 如果您没有c ++ 11访问权限,则可以使用boost::bindboost::function

First option: 第一种选择:

if the different methods are just a implementations of the same virtual method in different subclasses, ie. 如果不同的方法只是同一虚拟方法在不同子类中的实现,即 Base looks like: Base看起来像:

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

Then all of your method pointers have type bool (Base::*)() . 然后, 所有方法指针的类型都为bool (Base::*)() In this case, your problem is choosing an object to call this method on, so you presumably have a container of Base* pointers with different dynamic types. 在这种情况下,您的问题是选择一个对象来调用此方法,因此您大概拥有一个具有不同动态类型的Base*指针容器。


Second option: 第二种选择:

your classes are really unrelated, and you just want to call some function with signature bool (*)() without worrying about the object. 您的类实际上是无关的,并且您只想使用签名bool (*)()调用某些函数,而不必担心对象。

In this case, either: 在这种情况下,请执行以下任一操作:

  1. your classes and their instances are really irrelevant and you could just use static methods 您的类及其实例确实无关紧要,您可以使用静态方法
    • so just use free functions 所以只要使用自由功能
  2. you need an instance but don't know what type it is when choosing the function 需要一个实例,但是在选择函数时知道它是什么类型

    • you need a functor which can capture the instance, and provide a compatible nullary call operator. 您需要一个可以捕获实例并提供兼容的null调用运算符的函子。 As has already been suggested, std::function<bool()> is the simplest way. 正如已经建议的那样, std::function<bool()>是最简单的方法。 For example, you could populate a vector like so: 例如,您可以像这样填充向量:

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

      Note that the a and b objects are captured by value in the lambdas, so it no longer matters whether A and B have any kind of inheritance relationship. 请注意, ab对象是通过 lambda中的值捕获的 ,因此AB是否具有任何继承关系都不再重要。

You can use a combination of std::function and std::bind both of which are found in <functional> . 您可以使用std::functionstd::bind的组合,这两者都可以在<functional>中找到。

Example: 例:

#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");
    }
}

Outputs: 输出:

true
false

Well, technically you can create an array of pointers to member functions, although as others suggested, you probably shouldn't. 嗯,从技术上讲,您可以创建一个指向成员函数的指针数组,尽管正如其他人建议的那样,您可能不应该这样做。 This works: 这有效:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM