函数指针指向类成员函数

时间:2014-12-17 01:47:16

标签: c++

我想创建具有函数指针作为参数的函数。

#include <iostream>
using namespace std;

class test{

public:
    test(){};

    double tt(double input){
        return input;
    };

};

double fptr_test(double (*fptr)(double), double input){
    return fptr(input);
}


int main(){

    test t;
    cout << t.tt(3) << endl;
    cout << fptr_test(t.tt, 3) << endl;  // This line doesn't work
    cout << fptr_test(&test::tt, 3) << endl;  // This line can't compile

    return 1;
}

但它不起作用。 我怎么能把类成员函数作为参数传递?

我可以在没有实例化的情况下调用成员函数吗?

4 个答案:

答案 0 :(得分:4)

如果要将指针传递给成员函数,则需要使用成员函数指针,而不是通用自由函数的指针和调用它的对象。

两者都不是可选的。

double fptr_test(test& t, double (test::*fptr)(double), double input){
    return t.*fptr(input);
}

// call like this:
fptr_test(&test::tt, 3); // Your second try

答案 1 :(得分:3)

函数指针和成员函数指针具有不兼容的类型。例如,&test::tt的类型是

double (test::*)(double)

而不是

double (*)(double)

这种差异的原因是[非static]成员函数有一个隐藏参数:指向成员函数的对象的指针,即this。从成员函数中传出正常函数指针的方法是通过提供this指针的函数进行委托,因此需要额外的参数。

在C ++中,将函数指针作为函数的参数更有用,函数可以由函数自定义,而是采用函数对象。这种方法有两种形式:

  1. 快速方法是使函数对象类型成为模板参数,并直接传递您获得的任何函数对象。例如,您fptr_test()看起来像这样:

    template <typename Fun>
    double fptr_test(Fun fun, double input) {
        return fun(input);
    }
    

    使用的隐式概念是一个可调用double参数的函数,其结果可转换为double

  2. 特别是当被调用的函数需要单独编译时,对每种函数对象使用模板是不可行的。在这种情况下,使用类型擦除表示更合理,即std::function<...>,例如:

    double fptr_test(std::function<double(double)> fun, double input) {
        return fun(input);
    }
    
  3. 在这两种情况下,函数对象只接受一个参数,而您的成员函数接受两个:调用函数的对象和double参数。你是std::bind(...)对象的第一个参数,并将结果对象传递给fptr_test()

      test object;
      std::cout << fptr_test(std:bind(&test::tt, &object, std::placeholders::_1), 3) << '\n';
      std::cout << fptr_test([&](double input){ return object.tt(input); }, 3) << '\n';
    

    代码使用两种不同的方法来绑定对象:第一种使用std::bind()而第二种使用lambda函数。这两个调用都应该与fptr_test()提供的两个实现一起使用。

答案 2 :(得分:1)

你可能想要的是:

#include <iostream>
#include <functional>
using namespace std;

class test{

public:
    test(){};

    double tt(double input){
        return input;
    };

};

double fptr_test( std::function<double(double)> func, double input){
    return func(input);
}


int main(){
    using namespace std::placeholders;

    test t;
    cout << t.tt(3) << endl;
    cout << fptr_test( std::bind( &test::tt, t, _1 ), 3) << endl;

    return 0;
}

顺便说一句 - 当你的程序正确完成时,你想从main()

返回0

答案 3 :(得分:0)

以下是修改后的代码。

#include <iostream>
using namespace std;

class test{

public:
    test(){};

    double tt(double input){
        return input;
    };

};

double fptr_test(test* t, double (test::*fptr)(double), double input){
    return (t->*fptr)(input);
}

int main(){

    test t;
    cout << t.tt(3) << endl;
    cout << fptr_test(&t, &test::tt, 3) << endl;

    return 1;
}