类之间的函数指针

时间:2013-06-11 15:28:24

标签: c++ member-function-pointers

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

我的顶级课程是这样的:

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-&gt; addFnPtrToList(0,&amp; CTop :: func1);” 我得到的问题(非常正确)addFnPtrToList不接受参数(int,(CTop :: *)())。所以编译器知道这个函数是某个成员函数,而不仅仅是一个通用的(可能是静态的)函数。

有没有办法将指向成员函数的指针传递给子类?在我的情况下,我希望子类能够调用此函数。我想我可能不得不制作静态成员函数或其他东西,但语法是让我不知道如何做到这一点。

所有帮助/建议表示赞赏。 饲料

4 个答案:

答案 0 :(得分:4)

CTop::func1是会员功能。 &CTop::func1不是函数指针,它是指向成员(函数)的指针。那些不能混合存储或呼叫。它与int (*fn)(void)不兼容,因为后者不带参数,前者需要一个作为隐藏this传递的对象。

由于这些原因,你不能拥有简单但统一的设施。您可以使用简单的函数指针,或PTM +对象指针对,或使用包装 - 手工或库存boost::functionboost::bind推动。如果你有C ++ 11或TR1,你可以使用后者的std :: equivalent。

答案 1 :(得分:3)

表格中的声明:

int (*fn)(void)

无法指向成员函数。它只能指向自由功能。 Philplophically,这是因为成员函数的调用约定与自由函数的调用约定不同。例如,考虑在成员函数调用的上下文中需要this指针。

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

int (CTop::*fn)(void)

C++ FAQ中有一个专门用于成员函数指针的部分。看看吧。

答案 2 :(得分:1)

您正在传递成员函数,就好像它是常规函数一样。这不包括对该类的'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);

答案 3 :(得分:0)

这是最终的解决方案,它使用传递对象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的实例(以便可以调用指向函数的指针),然后模板类将其存储为指向给定模板类型的指针....啦!...容易:o

感谢所有贡献者:))