c++ 是否可以有一个指向一个类的成员函数的指针列表,作为另一个类的成员,这些函数将被调用?

dm7nw8vv  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(102)

假设我们有一个类A,它有几个具有相同函数签名的setter函数,如以下代码:

class A
{
public:
    void setter1(int whatever)
    {
        // set Something ...
    }
    
    void setter2(int whatever)
    {
        // set Something ...
    }
    
    void setter3(int whatever)
    {
        // set Something ...
    }
};

字符串
另一个类B有一个类A的对象。另一个类C有一个B的对象。在C中,我试图声明A的函数指针列表,并试图通过B的对象调用它们。
下面是我如何调用的例子:

class B
{
public:
    A objectA;
};
    
class C
{
    C()
    {
        for (auto fnc: fncList)
        {
            someFunc();
        }
    }
    
    void someFunc()
    {
        auto setterFnc = fncList .front();
        fncList.pop_front();
        objectB.objectA. // --> here I can't find the right syntax to call the function;
    } 

    std::list<void (A::*)(int)> fncList = {&A::setter1, &A::setter2, A::setter2};
};


是否有其他方法来声明函数指针列表,以便我可以从类A的任何函数通过B中的对象从C使用它?

brqmpdu1

brqmpdu11#

在类B的某个函数中,所有这些类A的函数将被一个接一个地调用。
是的,可以,如下所示。你必须有一个对象或一个指向你的类类型的对象的指针,以便使用指向这些成员函数的指针来调用成员函数。

C++17

在这里,你可以使用std::invoke来使用指向成员函数的指针,以使代码 * 更具可读性 *。

#include <functional> 
#include <list>
struct A
{

    void setter1(int whatever){}
    void setter2(int whatever){}
    void setter3(int whatever){}

};
struct B
{
   std::list<void (A::*)(int)> fncList = {&A::setter1, &A::setter2, &A::setter3};
   //lets add a ctor
   B( A &a, int i)
   {
          for(auto ptr: fncList)
          {
                std::invoke(ptr, a, i);  //calls each of the setter
          }
         
   }
};

字符串
Demo

C++17之前

在这里,我们将调用std::invoke(ptr, a, i)替换为:

(a.*ptr)(i);


Demo

daolsyd0

daolsyd02#

是的,这是可能的。虽然语法很恶心。

static constexpr void (A::* const setters_of_a[])(int)

字符串
这声明了一个核心常量数组setters_of_a,指向A类型函数的成员指针,该函数接受int并返回void

(a.*setter)(42);


这将调用对象a上指向成员setter的指针所引用的成员函数。

#include <iostream>
struct A
{
    void f(int) { std::cout << "A::f()\n";}
    void g(int) { std::cout << "A::g()\n";}
};

struct B
{
    A a;
    static constexpr void (A::* const setters_of_a[])(int) = { &A::f, &A::g };
    void set_a()
    {
        for (auto setter : setters_of_a) {
            (a.*setter)(42);
        }
    }
};

int main()
{
    B b;
    b.set_a();
}


Demo on Compiler Explorer

相关问题