获取指向对象成员函数的指针

发布于 2024-12-27 04:53:43 字数 638 浏览 1 评论 0原文

我有这样的类

class some_class
{
public:
    some_type some_value;
    int some_function(double *a, double *b, int c, int d, void *e);
};

some_function 内,我使用 some_class 对象中的 some_values 来获取结果。

所以,我有一个具体的对象,我想获取指向该对象some_function的指针。

是否可以?我无法使用 some_fcn_ptr,因为该函数的结果取决于对象的具体 some_value

如何获取指向对象的 some_function 的指针?

typedef  int (Some_class::*some_fcn_ptr)(double*, double*, int, int, void*);

I have class like so

class some_class
{
public:
    some_type some_value;
    int some_function(double *a, double *b, int c, int d, void *e);
};

Inside some_function, I use some_values from some_class object to get a result.

So, I have a concrete object, and I want to get a pointer to this object some_function.

Is it possible? I can't use some_fcn_ptr, because, the result of this function depends on the concrete some_value of an object.

How can I get a pointer to some_function of an object?

typedef  int (Some_class::*some_fcn_ptr)(double*, double*, int, int, void*);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

◇流星雨 2025-01-03 04:53:43

你不能,至少它不仅仅是一个指向函数的指针。

成员函数对于此类的所有实例都是通用的。所有成员函数都有隐式(第一个)参数 this。为了调用特定实例的成员函数,您需要一个指向该成员函数和该实例的指针。

class Some_class
{
public:
    void some_function() {}
};

int main()
{
    typedef void (Some_class::*Some_fnc_ptr)();
    Some_fnc_ptr fnc_ptr = &Some_class::some_function;

    Some_class sc;

    (sc.*fnc_ptr)();

    return 0;
}

更多信息请参见 C++ 常见问题解答

使用 Boost 这看起来像(C++11 提供类似的功能):

#include <boost/bind.hpp>
#include <boost/function.hpp>

boost::function<void(Some_class*)> fnc_ptr = boost::bind(&Some_class::some_function, _1);
Some_class sc;
fnc_ptr(&sc);

C++11 的 lambda:

#include <functional>

Some_class sc;
auto f = [&sc]() { sc.some_function(); };
f();
// or
auto f1 = [](Some_class& sc) { sc.some_function(); };
f1(sc);

You cannot, at least it won't be only a pointer to a function.

Member functions are common for all instances of this class. All member functions have the implicit (first) parameter, this. In order to call a member function for a specific instance you need a pointer to this member function and this instance.

class Some_class
{
public:
    void some_function() {}
};

int main()
{
    typedef void (Some_class::*Some_fnc_ptr)();
    Some_fnc_ptr fnc_ptr = &Some_class::some_function;

    Some_class sc;

    (sc.*fnc_ptr)();

    return 0;
}

More info here in C++ FAQ

Using Boost this can look like (C++11 provides similar functionality):

#include <boost/bind.hpp>
#include <boost/function.hpp>

boost::function<void(Some_class*)> fnc_ptr = boost::bind(&Some_class::some_function, _1);
Some_class sc;
fnc_ptr(&sc);

C++11's lambdas:

#include <functional>

Some_class sc;
auto f = [&sc]() { sc.some_function(); };
f();
// or
auto f1 = [](Some_class& sc) { sc.some_function(); };
f1(sc);
愛上了 2025-01-03 04:53:43

不,您无法获取指向 C++ 类方法的指针(除非该方法被声明为静态)。原因是类方法始终具有指针 this,它是指向类实例的指针。但是如果你通过指针调用该方法,该指针无法封装 this 指针,那么就不会附加任何实例,因此这种行为是不合法的。

No, you can't get a pointer to a C++ class method (unless the method is declared static). The reason is that a class method always has the pointer this, a pointer to the class instance. But were you to call the method through a pointer, that pointer could not encapsulate the this pointer, and then then there would be no instance attached, and therefore this behavior is not legal.

凡尘雨 2025-01-03 04:53:43

您可以编写某种能够使用函数或方法作为参数的包装器。

我使用以下类来启动函数(它在我的一个 SDL 程序中使用):

class CallbackFunction {
public:
    // Constructor, copy constructor and destructor

    virtual int execute( SDL_keysym* keysym) const;
    virtual int operator()( SDL_keysym* keysym) const;

protected:
    int( *callback)( SDL_keysym*));
}

int CallbackFunction::execute( SDL_keysym* keysym) const{
    return callback(keysym);
}

int CallbackFunction::operator()( SDL_keysym* keysym) const{
    return callback( keysym);
}

以及“方法”的这个扩展:

template<class T>
class CallbackMethod : public CallbackFunction {
public:
    // Constructor, copy constructor and destructor
    CallbackMethod( T *object, int(T::*callback)( SDL_keysym* keysym));

    int execute( SDL_keysym* keysym) const;
    int operator()(SDL_keysym* keysym) const;

protected:
    T *object;
    int(T::*method)( SDL_keysym* keysym);
};

// Object initialization (constructor)
template<class T>
CallbackMethod<T>::CallbackMethod( T *object, int(T::*callback)( SDL_keysym* keysym)):
    CallbackFunction( NULL),object(object),method(callback){
}


// Responsible for executing
template<class T>
int CallbackMethod<T>::execute( SDL_keysym* keysym) const {
    return (object->*method)(keysym);
}
template<class T>
int CallbackMethod<T>::operator()( keysym) const {
    return (object->*method)( keysym);
}

然后将其用作:

CallbackFunction *callback;
callback = new CallbackFunction( myFunction);
callback = new CallbackMethod<A>( instanceOfA, instanceOfA::myMethod);
callback = new CallbackMethod<B>( instanceOfB, instanceOfB::myMethod);
...
callback( keysym);

我发现宏是这样的:

CALLBACK(object,method) new CallbackMethod<typeof(*object)>( object, &method)

真的很有用

You may write some kind of Wrapper which is able to use both function or method as parameter.

I used following classes for launching functions (it was used in one my SDL program):

class CallbackFunction {
public:
    // Constructor, copy constructor and destructor

    virtual int execute( SDL_keysym* keysym) const;
    virtual int operator()( SDL_keysym* keysym) const;

protected:
    int( *callback)( SDL_keysym*));
}

int CallbackFunction::execute( SDL_keysym* keysym) const{
    return callback(keysym);
}

int CallbackFunction::operator()( SDL_keysym* keysym) const{
    return callback( keysym);
}

And this extension for "methods":

template<class T>
class CallbackMethod : public CallbackFunction {
public:
    // Constructor, copy constructor and destructor
    CallbackMethod( T *object, int(T::*callback)( SDL_keysym* keysym));

    int execute( SDL_keysym* keysym) const;
    int operator()(SDL_keysym* keysym) const;

protected:
    T *object;
    int(T::*method)( SDL_keysym* keysym);
};

// Object initialization (constructor)
template<class T>
CallbackMethod<T>::CallbackMethod( T *object, int(T::*callback)( SDL_keysym* keysym)):
    CallbackFunction( NULL),object(object),method(callback){
}


// Responsible for executing
template<class T>
int CallbackMethod<T>::execute( SDL_keysym* keysym) const {
    return (object->*method)(keysym);
}
template<class T>
int CallbackMethod<T>::operator()( keysym) const {
    return (object->*method)( keysym);
}

And then use it as:

CallbackFunction *callback;
callback = new CallbackFunction( myFunction);
callback = new CallbackMethod<A>( instanceOfA, instanceOfA::myMethod);
callback = new CallbackMethod<B>( instanceOfB, instanceOfB::myMethod);
...
callback( keysym);

I found macro as this:

CALLBACK(object,method) new CallbackMethod<typeof(*object)>( object, &method)

really useful

不再让梦枯萎 2025-01-03 04:53:43

虽然不完全符合您的要求,但如果您可以使用 C++11,以下内容可能仍然适合您的需求(未经测试):

std::function<int(double*, double*, int, int, void*)>
  some_function_of(Some_class& obj)
{
  return [&](double* a, double* b, int c, int d, void* e){
    return obj.some_func(a, b, c, d, e); };
}

While not exactly what you requested, if you can use C++11 the following might nevertheless suit your needs (untested):

std::function<int(double*, double*, int, int, void*)>
  some_function_of(Some_class& obj)
{
  return [&](double* a, double* b, int c, int d, void* e){
    return obj.some_func(a, b, c, d, e); };
}
柒夜笙歌凉 2025-01-03 04:53:43

我使用了 Boost 库。我在代码中包含了“boost/bind.hpp”。然后,可以将名为“fn”的方法定义为

auto fn = boost::bind(ClassName::methodName, classInstanceName, boost::placeholders::_1);

I used the Boost library. I included "boost/bind.hpp" in my code. Then a method named "fn" can be defined as

auto fn = boost::bind(ClassName::methodName, classInstanceName, boost::placeholders::_1);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文