避免使用类范围,以便将成员函数作为函数指针传递

时间:2016-07-21 13:56:09

标签: c++ c++11 c++14

我将使用以下示例代码描述我的问题。

我将B类定义如下:

class B
{
    public:
        inline B(){}
        inline B(int(*f)(int)) :myfunc{ f }{}
        void setfunction(int (*f)(int x)) { myfunc = f; }
        void print(int number) { std::cout << myfunc(number) << std::endl; }
    private:
        int(*myfunc)(int);
};

然后我按如下方式定义A类:

class A
{
    public:
    A(int myint) :a{ myint }{ b.setfunction(g); }
    int g(int) { return a; }
    void print() { b.print(a); }

   private:
   B b;
   int a;
   };

对我来说,问题似乎是成员函数g具有签名int A::g(int)而不是int g(int)

是否有标准的方法来完成上述工作?我想这是一个非常普遍的设置,因为我们有一个类(B类),它包含某些执行某些操作的成员函数,并且我们有一个类(A类)需要使用类的特定成员函数B - 所以我的设计是错误的,如果是这样,表达这个想法的最佳方式是什么?

4 个答案:

答案 0 :(得分:3)

您可以使用std :: function:

<FilesMatch "">

答案 1 :(得分:2)

您可以概括课程B。你不是要保留指针(int(*)(int)),而是我可以使用int调用并返回另一个int的任何内容。出于这个原因,C ++ 11引入了类型擦除函数异议:std::function<int(int)>

class B
{
    using F = std::function<int(int)>
public:
    B(){}
    B(F f) : myfunc(std::move(f)) { }
    void setfunction(F f) { myfunc = std::move(f); }
    void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
    F myfunc;
};

然后你可以从B A提供一般调用A(int myint) : b([this](int a){ return g(a); }) , a{ myint } { }

function diff($arr1, $arr2){      
    $arr3=array();
    for($i=0;$i<count($arr1);$i++){
        $arr3[$i]=$arr1[$i]-$arr2[$i];
    }
    print_r($arr3);
}
$arr1=array(300,300,300);
$arr2=array(100,100,100);
diff($arr1, $arr2);
//Displays 200, 200, 200, as expected

答案 2 :(得分:1)

使用std::functionstd::bind

class B
{
    public:
        inline B(int(*f)(int)) :myfunc{ f }{}
        void setfunction(std::function<int(int)> f) { myfunc = f; }
        void print(int number) { std::cout << myfunc(number) << std::endl; }
    private:
        std::function<int(int)> myfunc;
};

// ...
A a;
B b(std::bind(&A::g, &a));

另请注意,您应该将函数指针初始化为某个默认值(很可能为null)并在使用时检查它,否则它的值是未定义的。

答案 3 :(得分:1)

您可以使用std::bind绑定成员函数A::g

class B
{
    public:
        inline B(){}
        inline B(std::function<int(int)> f) :myfunc{ f }{}
        void setfunction(std::function<int(int)> f) { myfunc = f; }
        void print(int number) { std::cout << myfunc(number) << std::endl; }
    private:
        std::function<int(int)> myfunc;
};
class A
{
    public:
        A(int myint) :a{ myint } { 
            b.setfunction(std::bind(&A::g, this, std::placeholders::_1)); 
        }
        int g(int) { return a; }
        void print() { b.print(a); }

    private:
        B b;
        int a;
};

请注意,您需要将函数指针的类型更改为std::function,这适用于std::bind

LIVE