c++存储指向未知类的成员函数的指针

发布于 2024-12-10 01:59:00 字数 343 浏览 1 评论 0原文

我想存储一个指向对象的指针和一个指向其已知签名方法的指针。如果我知道该类,那么该指针就有类型:

int (MyClass::*pt2Member)(float, char, char)

但是如果我不知道该类型,我如何存储该指针?

我想做这样的事情:

myObject.callThisFuncLater(&otherObject, &otherObject::method)

如何在 myObject 中存储指向方法 method 的指针并稍后调用它?

I want to store a pointer to an object and a pointer to it's method of known signature. If I know the class then this pointer have type:

int (MyClass::*pt2Member)(float, char, char)

But how can i store the pointer if i don't know the type?

I want to do something like this:

myObject.callThisFuncLater(&otherObject, &otherObject::method)

How can i store a pointer to method method in myObject and call it later ?

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

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

发布评论

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

评论(4

七月上 2024-12-17 01:59:00

如果您有权访问 TR1 STL 库扩展(在 gcc 和 Visual Studio 2008 及更高版本上可用),最简单的方法是。 std::function 和 std::bind 可用于包装稍后调用的调用。此功能在 boost 函数和 boost 绑定中也可用:

#include <functional>

class MyClass {
public:
  template<typename T> callThisFuncLater(T& otherObject,
                                         int(T::*)(float, char, char) method) {
    return storedInvocation_ = std::bind(otherObject, 
                                  method, 
                                  std::placeholders::_1,   // float
                                  std::placeholders::_2,   // char
                                  std::placeholders::_3);  // char
  }

  int callStoredInvocation(float a, char b, char c) {
    storedInvocation_(a, b, c);
  }

private:
  std::function<int(float, char, char)> storedInvocation_;
};

The easiest way to do it if you have access to the TR1 STL library extensions (available on gcc and Visual Studio 2008 and onwards is. std::function and std::bind can be used to wrap an invocation which can be called later. This functionality is also available in boost function and boost bind:

#include <functional>

class MyClass {
public:
  template<typename T> callThisFuncLater(T& otherObject,
                                         int(T::*)(float, char, char) method) {
    return storedInvocation_ = std::bind(otherObject, 
                                  method, 
                                  std::placeholders::_1,   // float
                                  std::placeholders::_2,   // char
                                  std::placeholders::_3);  // char
  }

  int callStoredInvocation(float a, char b, char c) {
    storedInvocation_(a, b, c);
  }

private:
  std::function<int(float, char, char)> storedInvocation_;
};
卖梦商人 2024-12-17 01:59:00

没有简单的方法可以像最初内置到语言或标准库中那样执行此操作(尽管最近已添加)。如果您熟悉 Boost,他们提供了一个解决方案 - Boost.Function

但是,如果由于某种原因,您无法或不愿意使用 Boost,则可以使用模板来执行此操作(不可否认,这与 Boost 的解决方案非常相似):

class FncPtr
{
public:
    virtual int call(float, char, char) = 0;
};

template <typename T>
class ClassFncPtr : public FncPtr
{
     int (T::*pt2Member)(float, char, char);
     T *inst;
public:
     ClassFncPtr(T* who, int (T::*memfunc)(float,char,char))
         : inst(who), pt2Member(memfunc)
     {
     }
     int call(float a, char b, char c)
     {
         return (inst->*pt2Member)(a,b,c);
     }
};

template <typename T>
FncPtr * makeFuncPointer(T* who, int (T::*memfunc)(float,char,char))
{
    return new ClassFncPtr<T>(who,memfunc);
}

您还可以子类化 FncPtr 以便能够使用非类函数(如果您愿意)。

There is no simple way of doing this as originally built into the language or standard library (although, it has recently been added). If you're familiar with Boost, they include a solution for this - Boost.Function.

If for some reason, however, you're unable or unwilling to use Boost, there is a generic way of doing this using templates (which, admittedly, is rather similar to Boost's solution):

class FncPtr
{
public:
    virtual int call(float, char, char) = 0;
};

template <typename T>
class ClassFncPtr : public FncPtr
{
     int (T::*pt2Member)(float, char, char);
     T *inst;
public:
     ClassFncPtr(T* who, int (T::*memfunc)(float,char,char))
         : inst(who), pt2Member(memfunc)
     {
     }
     int call(float a, char b, char c)
     {
         return (inst->*pt2Member)(a,b,c);
     }
};

template <typename T>
FncPtr * makeFuncPointer(T* who, int (T::*memfunc)(float,char,char))
{
    return new ClassFncPtr<T>(who,memfunc);
}

You can also subclass FncPtr to be able to use non-class functions, if you'd like.

‖放下 2024-12-17 01:59:00

您可以使用 boost::function (和 boost::bind)来存储一段稍后调用的代码。

class MyClass
{
public:
    void callThisFuncLater( boost::function< int (float, char, char) > callBack );
};
...
myObject.callThisFuncLater( boost::bind( &otherObject::method, &otherObject ) );

You can use boost::function (and boost::bind) to store a piece of code to be called later.

class MyClass
{
public:
    void callThisFuncLater( boost::function< int (float, char, char) > callBack );
};
...
myObject.callThisFuncLater( boost::bind( &otherObject::method, &otherObject ) );
傲性难收 2024-12-17 01:59:00

我个人会选择不同的设计。仅仅是因为 C++ 中的成员函数指针不容易使用。就我个人而言,我会选择使用接口并继承这些接口并沿着这些接口进行解析。

成员函数指针的问题之一是它们在不同编译器上的实现方式不同。如果您使用 Borland/Embarcardero 编译器并希望将自己限制于此,您可以使用 __closure 关键字,但很可能您不是,因此您必须使用其他编译器特定的实现,或者使用 boost 帮助器类之一,例如函数。

但是,如果您发现在 C++ 中使用成员函数指针很有帮助,请重新考虑您的设计。

Personally I would choose a different design. Simply because member function pointers in C++ are not easy to work with. Personally I would choose to use interfaces and inherit from these and parse along these.

One of the problems with member function pointers is that they are implemented differently on different compilers. If you use the Borland/Embarcardero compilers and want to limit yourself to this, you can use the __closure keyword, however most likely you are not, and therefore you would have to either use some other compiler specific implementation, or use one of the boost helper classes like function.

But if you are in a situation where you find it helpful to use member function pointers in C++, reconsider your design.

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