0

我想写一些驱动程序来使用下面的一个类:但我不明白这个类的声明以及如何使用它。我想了解这门课并使用它,所以我想学什么来深入了解这门课。先谢谢了!:

typedef void (*pvoidf_t)(void);

/* A class for storing and calling a pointer to a static or member void function */

class FunctionPointer {

public:

    FunctionPointer(void (*function)(void) = 0);

    /** Create a FunctionPointer, attaching a member function
     *
     *  @param object The object pointer to invoke the member function on (i.e. the this pointer)
     *  @param function The address of the void member function to attach
     */
    template<typename T>
    FunctionPointer(T *object, void (T::*member)(void)) {
        attach(object, member);
    }

    /** Attach a static function
     *
     *  @param function The void static function to attach (default is none)
     */
    void attach(void (*function)(void) = 0);

    /** Attach a member function
     *
     *  @param object The object pointer to invoke the member function on (i.e. the this pointer)
     *  @param function The address of the void member function to attach
     */
    template<typename T>
    void attach(T *object, void (T::*member)(void)) {
        _object = static_cast<void*>(object);
        memcpy(_member, (char*)&member, sizeof(member));
        _membercaller = &FunctionPointer::membercaller<T>;
        _function = 0;
    }

    /** Call the attached static or member function
     */
    void call();

    pvoidf_t get_function() const {
        return (pvoidf_t)_function;
    }

private:

    template<typename T>
    static void membercaller(void *object, char *member) {
        T* o = static_cast<T*>(object);
        void (T::*m)(void);
        memcpy((char*)&m, member, sizeof(m));
        (o->*m)();
    }

    void (*_function)(void);                // static function pointer - 0 if none attached
    void *_object;                            // object this pointer - 0 if none attached
    char _member[16];                        /* raw member function pointer storage - converted back by registered _membercaller */
    void (*_membercaller)(void*, char*);    /* registered membercaller function to convert back and call _member on _object */

};
4

1 回答 1

0

首先,我将解决评论:

template<typename T>
FunctionPointer(T *object, void (T::*member)(void)) {
    attach(object, member);
}

类的这一部分声明了一个构造函数模板,类似于成员函数模板。它的参数是:

  • 指向类型对象的指针T,名为object
  • 和一个指向T没有参数也没有返回值的成员函数的指针,命名为member

后者的语法可以解读为:

void   (T  ::  *  member)  (void)
^       ^      ^  ^        ^ argument list
|       |      |  | name of the parameter
|       |      | it's a pointer
|       | class type
| return type

现在,其余的功能:

FunctionPointer(void (*function)(void) = 0);

这是一个(非模板)构造函数,其参数指针指向一个没有参数且没有返回值的函数,名为function。该参数有一个默认参数0

成员函数的重载签名attach可以和构造函数类似地理解。

get_function现在终于使用了 typedef: typedef void (*pvoidf_t)(void);,它为类型指针定义了一个别名,该指针指向一个没有参数也没有返回值的函数。对于该类的非模板函数(和构造函数)也可以这样做:

FunctionPointer(pvoidf_t function = 0);

这是上面显示的非模板构造函数声明的等效替代。


整个类旨在存储函数指针或成员函数指针。指向静态成员函数的指针与指向自由函数的指针没有什么不同,但指向非静态成员函数的指针是:至少,它需要一个类的实例来操作:

struct my_class
{
    int m;
    void set_m() { m = 42; }
};

typedef void (my_class::*mem_fun_ptr)();
mem_fun_ptr p_set_m = &my_class::set_m;

my_class instance;
(instance.*p_set_m)(); // we need an instance to call the member function

因此,类在存储成员函数指针时,FunctionPointer还需要存储指向实例的指针。

第二个问题出现了,因为成员函数指针的类型依赖于成员函数的类。的类型与void (class_A::*)()不同void (class_B::*)()

从函数membercaller和私有变量中,我们可以猜测这些问题是如何解决的FunctionPointer

  • 对于任何普通(自由)函数指针,使用数据_function成员
  • 对于任何成员函数指针:
    1. 数据成员_object设置为指向传递的实例
    2. 成员函数指针被复制到缓冲区(希望足够大),数据成员_member
    3. 数据成员_membercaller被设置为指向membercaller静态函数模板的一个实例。这是至关重要的一步:在 ctor/ 内部attach,我们仍然知道成员函数指针的类类型,但是一旦返回,我们就会丢失它。membercaller因此,类型在我们指向的模板实例中被“编码”了。这个函数“知道”类类型,因为它的模板参数。对于每个不同的类类型,membercaller都会创建一个新实例,例如membercaller<class_A>membercaller<class_B>等等。这些是不同的功能,可能具有不同的地址和可能不同的行为。
    4. 数据成员_function设置为0

进一步猜测:对于任何调用,call都使用了成员函数。如果_function不是0,则直接调用_function()。如果_function0,它调用_membercaller(_object, _member),它解析membercaller为对成员函数调用的具有“正确”类类型的实例的调用。


如何使用这个类的两个例子:

void my_function() {
    // do something
}

FunctionPointer myptr(&my_function);
// store myptr, do something else
myptr.call();  // calls (indirectly) `my_function`

使用成员函数指针:

struct my_class {
    int m;
    void my_function() { /*...*/ }
};

my_instance inst = {42};

FunctionPointer myptr(&inst, &my_class::my_function);
// store myptr, do something else

// make sure `inst` lives until after the call!
myptr.call();  // calls (indirectly) `inst.my_function()`
于 2013-10-03T13:35:49.250 回答