类之间的函数指针

function pointers between classes

本文关键字:指针 函数 之间      更新时间:2023-10-16

我很难理解如何将类成员函数传递给子类(而不是派生)。

我的顶级类是这样的:

class CTop
{
public:
    CTop();
    int func1(void);
private:
    CFnList* _funcList;
};
CTop::CTop():
    _funcList(0)
{
    _funcList = new CFnList();
    _funcList->addFnPtrToList(0, &CTop::func1);
}
int CTop::func1(void)
{
    // Does some stuff...
}

函数列表类是这样的:

class CFnList
{
public:
    // Public functions
    CFnList();
    void addFnPtrToList(int index, int (*fn)(void));
private:
    // Fn pointer list
    typedef struct
    {
        int index;
        int (*fn) (void);
    }fn_list_t;
    // function pointer list
    QVector<fn_list_t> _fn_list;
};

这里我有一个类CTop的实例它的一个成员是指向类CFnList的指针。CFnList指针在CTop的构造函数中实例化。然后,我想通过调用下面的行来传递一个指向CTop成员函数之一的指针给CFnList:"_funcList -> addFnPtrToList(0,和CTop:: func1);"我得到的问题(相当正确),addFnPtrToList不接受参数(int, (CTop::*)())。因此,编译器知道这个函数是一个特定的成员函数,而不仅仅是一个泛型(可能是静态)函数。

是否有一种方法来传递指针的成员函数到子类?在我的情况下,我希望子类能够调用这个函数。我想我可能要做静态成员函数或其他东西,但语法是逃避我如何做到这一点。

感谢所有的帮助/建议。饲料

CTop::func1是成员函数。&CTop::func1不是函数指针,它是指向成员(函数)的指针。它们在存储和调用上都不能混合。它与int (*fn)(void)不兼容,因为后者不带参数,而前者需要传递一个对象作为隐藏的this

由于这些原因,你不可能拥有一个简单而统一的设施。您可以使用简单的函数指针,或成对的PTM+对象指针,或使用包装器-手工或库存,如boost::bind驱动的boost::function。如果您使用的是c++ 11或TR1,则可以使用后者的等效std::。

格式的声明:

int (*fn)(void)

不能指向成员函数。它只能指向一个自由函数。从哲学上讲,这是因为成员函数的调用约定与自由函数的调用约定不同。例如,考虑在成员函数调用上下文中需要this指针。

声明指向成员函数的指针的语法如下:

int (CTop::*fn)(void)

c++ FAQ中有一整节专门讨论成员函数指针。

就像传递普通函数一样传递成员函数。这没有包括对类的"this"引用。为了传递成员函数,您必须能够从原始的"this"重新引用它。请看下面的

typedef void (CTop::*OBJFNC)(args);
_funcList = new CFnList();
_funcList->addFnPtrToList(0, this, &CTop::func1);

void addFnPtrToList(int index, CTop* pobj, OBJFNC pfnc)
{ ... Store both ...
}

现在,您可以在其他地方执行以下命令:

(pobj->*pfnc)(args);

这是最终的解决方案,它使用了传递对象CTop的实例和使用CFnList的模板类的混合:

我的顶级类是这样的(除了_funcList的声明包含类类型并将"this"传递给构造函数之外,几乎相同):

class CTop
{
public:
    CTop();
    int func1(void);
private:
    CFnList<CTop>* _funcList;
};
CTop::CTop():
    _funcList(0)
{
    _funcList = new CFnList(this);
    _funcList->addFnPtrToList(0, &CTop::func1);
}
int CTop::func1(void)
{
    // Does some stuff...
}

函数列表类是这样的:

template<class T>
class CFnList
{
public:
    // Public functions
    CFnList(T *parent);
    void addFnPtrToList(int index, int (T::*fn)(void));
private:
    // Pointer to the parent (or owner is perhaps more correct)
    T* _parent;
    // Fn pointer list
    typedef struct
    {
        int index;
        int (T::*fn) (void);
    }fn_list_t;
    // function pointer list
    QVector<fn_list_t> _fn_list;
};
// Constructor
template <class T>
CFnList<T>::CFnList(T *parent) :
    _parent(parent),
    _fn_list(0)
{
}
// addFnPtrToList:
template <class T>
void CFnList<T>::addFnPtrToList(int index, int (T::*fn)(void))
{
    _fn_list.append((fn_list_t){index, fn});
}

所以主要的变化是:1. 通过将CFnList更改为模板来传递CTop类型。2. 通过将"this"传递给构造函数来传递对象CTop的实例(以便可以调用函数的指针),然后模板类将其存储为指向给定模板类型....的指针vio-la !…容易:o

感谢所有贡献的人:))