c++ - 类成员函数作为函数指针

标签 c++ class function-pointers member-functions

我有一个类,它的一个成员函数实际上是一个函数指针。这样用户就可以覆盖这个函数的作用。不幸的是,我在运行这个功能时遇到了一些困难。我使用 g++ 编译。

代码如下:

    #include <iostream>

    using namespace std;

    double fcn_mod(const double &phit){
        return 1.2+phit;
    }

    class Object{
        public:
            Object() {
                fcn_ptr = (double (*)(const double &)) &Object::fcn_default;
            }
            double (*fcn_ptr)(const double &) = NULL;

        private:
            double fcn_default(const double &phit){
                return 3.2+phit;
            }
    };


    int main(){

        Object test1,test2;

        cout << (test1.*fcn_ptr)(2) << endl; // can not compile here

        test2.fcn_ptr = &fcn_mod;
        cout << (test2.*fcn_ptr)(2) << endl; // and here

        cout << "test" << endl;
    }

错误信息是:

    erreur: ‘fcn_ptr’ was not declared in this scope

+++++ 更新 1+++++

考虑到评论,这是一个更清晰的版本:

    #include <iostream>

    using namespace std;

    double fcn_mod(const double &phit){
        return 1.2+phit;
    }

    double fcn_default(const double &phit){
        return 3.2+phit;
    }

    class Object{
        public:
            double (*fcn_ptr)(const double &) = NULL;
            Object() {
                fcn_ptr = &fcn_default;
            }

    };


    int main(){

        Object test1,test2;

        cout << (test1.*fcn_ptr)(2) << endl; // can not compile here

        test2.fcn_ptr = &fcn_mod;
        //cout << (test2.*fcn_ptr)(2) << endl; // and here

        cout << "test" << endl;
    }

这也是一种更好的方法:

    #include <iostream>

    using namespace std;

    double fcn_mod(const double &phit){
        return 1.2+phit;
    }

    class Object{
        public:
            Object() {
                fcn_ptr = &fcn_default;
            }
            double (*fcn_ptr)(const double &) = NULL;
        private :
            static double fcn_default(const double &phit){
                return 3.2+phit;
            }
    };

    int main(){
        Object test1,test2;
        cout << (test1.*fcn_ptr)(2) << endl; // can not compile here
        test2.fcn_ptr = &fcn_mod;
        cout << (test2.*fcn_ptr)(2) << endl; // and here
        cout << "test" << endl;
    }

+++++ 更新 2+++++

如果我想通过这个函数访问类的成员怎么办?

最简单的解决方案将无法从 fcn_mod 中授予对类成员 (aa) 的访问权限。

#include <iostream>

using namespace std;

double fcn_mod(const double &phit){
    return 1.2 + phit + aa*0.001; // can not compile here
}

class Object{
    public:
        Object() {
            fcn_ptr = &Object::fcn_default;
            aa = 4;
        }
        double (*fcn_ptr)(const double &) = NULL;
        double aa;

    private:
        static double fcn_default(const double &phit){
            return 3.2 + phit + aa*0.001; // and here
        }
};

int main(){
    Object test1,test2;
    cout << (test1.fcn_ptr)(2) << endl;
    test2.fcn_ptr = &fcn_mod;
    cout << (test2.fcn_ptr)(2) << endl;
    cout << "test" << endl;
}

但是使用 std::bind 和 std::function 的解决方案也没有。我可以将一种“静态”参数传递给函数指针吗?

我添加了网关功能。

#include <iostream>

using namespace std;

double fcn_mod(const double &phit){
    return 1.2 + phit;
}

class Object{
    public:
        Object() {
            fcn_ptr = &Object::fcn_default;
            aa = 4;
        }
        double do_something(const double &phit){
            return this->fcn_ptr(phit+aa*0.001);
        }
        double (*fcn_ptr)(const double &);
        double aa;

    private:
        static double fcn_default(const double &phit){
            return 3.2 + phit;
        }
};

int main(){
    Object test1,test2;
    cout << test1.do_something(2) << endl; // can not compile here
    test2.fcn_ptr = &fcn_mod;
    cout << test2.do_something(2) << endl; // and here
    cout << "test" << endl;
}

最佳答案

您尝试做的事情是行不通的。指向非静态成员函数的指针与指向自由函数的指针不同,因为与后者不同,前者必须在对象的实例上调用。因此,您不能声明一种类型的变量并将指向另一种类型的函数的指针分配给它。

首先,让我们修复一半的代码:

因为 fcn_ptr 是指向成员函数的指针,所以它的定义需要是:

double (Object::*fcn_ptr)(const double &) = NULL;

然后,构造函数中的强制转换无效。您试图将指向成员函数的指针转换为指向自由函数的指针。摆脱类型转换。

Object() : fcn_ptr(&Object::fcn_default)
{}

最后,当您调用 fcn_ptr 时,您不能凭空想出它。它是 Object 的数据成员,因此您需要该类的实例才能访问 fcn_ptr。所以称它为:

(test1.*(test1.fcn_ptr))(2)

进行所有这些更改,您的一半代码将编译并产生正确的结果。 Live demo


另一半,由于前面所述的原因,您尝试将指向自由函数的指针分配给 fcn_ptr 仍然无法正常工作。解决此问题的方法是使用 std::function 而不是函数指针。

class Object{
    public:
        Object() : fcn_ptr(std::bind(&Object::fcn_default, this, std::placeholders::_1))
        {}
        std::function<double(double const&)> fcn_ptr;

    private:
        double fcn_default(const double &phit){
            return 3.2+phit;
        }
};

然后将其用作:

cout << (test1.fcn_ptr)(2) << endl;

test2.fcn_ptr = &fcn_mod;
cout << (test2.fcn_ptr)(2) << endl;

Live demo

关于c++ - 类成员函数作为函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24195579/

相关文章:

java - 如何在 Java 中调用另一个类的方法?

c - 如何使用函数指针数组?

javascript - 在网络浏览器上显示保存的文件

c++ - 找不到匹配项

c++ - 无法在函数调用之外更改节点参数

你能在 C 中拥有带指定参数值的函数指针吗?

c++ - 如何将成员函数传递给函数指针?

c++ - 列表框通知

c++ - 使用 vector 的二维数组

java - Android应用程序模块化(类)