繁体   English   中英

类成员函数作为函数指针

[英]Class member function as function pointer

我有一个类,它的成员函数之一实际上是一个函数指针。 这样,用户可以覆盖此功能的作用。 不幸的是,我在运行此功能时遇到一些困难。 我使用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 ,您不能简单地fcn_ptr它。 它是Object的数据成员,因此您需要类的实例才能访问fcn_ptr 所以称它为:

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

进行所有这些更改,一半的代码将编译并产生正确的结果。 现场演示


另一半,由于前面提到的原因,您尝试将指向fcn_ptr的自由函数的指针分配给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;

现场演示

您没有一个带有“函数是函数指针”的类,而是有一个带有数据成员是函数指针的类。 这是一个重要的区别,因为该函数将不会接收this指针,也不会访问受保护的成员或私有成员。

您已经正确声明了函数指针,但是需要使用.fcn_ptr而不是.*fcn_ptr 我相信这足以解决您的问题。

请注意,您正在使用旧的C样式函数指针语法。 您可能想学习C ++函数指针的替代方案,包括std::function

暂无
暂无

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

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